OmniAICreator/Qiita-1.07M huggingface dataset:
M&Aとは

## M&A
M&Aは、Mergers and Accuisitionsの略で、合併と買収のことである。

M&Aが行われる企業間の関係性によって、「垂直統合」や「水平統合」、「混合型」などに分類される。

垂直統合は、買収する企業と買収される企業が、サプライチェーン上での上下関係になっている場合の統合。携帯電話メーカーと携帯電話の販売業者の統合など。

水平統合は、買収する企業と買収される企業が同業他社である場合の統合。ギターのメーカーとピアノのメーカーの統合など。

混合型は、買収する企業と買収される企業が異なる業界の他社である場合の統合。ゲームメーカーと衣料メーカーの合併など。
React Router v7にリセットCSSを適用する

## 経緯
- Viteで構築したReactのプロジェクトに React Router v7 を導入して遊んでた
- サイドバー作りたいなと思ってサイドバーとメインコンテンツを分けるフレームコンポーネントを作成
- mui使ってて、横並びにする設定してるのにサイドバーとメインコンテンツが横並びにならない
- DevToolsで要素を確認してみるとbodyタグに `display: flex` がついてるのが原因っぽい
- これはそもそもViteで生成されたデフォルトの `index.css` に設定されている

## リセットCSSを使う
React Router v7では `index.html` も不要になるんですがこの際だから `index.css` も削除してリセットCSSを当てようと思って `normalize.css` を使うことにしました。

```tsx:entry.client.tsx
import { StrictMode } from "react";
import ReactDOM from "react-dom/client";
import { HydratedRouter } from "react-router/dom";
import "normalize.css"; // ここをindex.cssにしたままだった！

ReactDOM.hydrateRoot(
	document,
	<StrictMode>
		<HydratedRouter />
	</StrictMode>,
);
```
```tsx:root.tsx
export const Layout = ({
	children,
}: {
	children: React.ReactNode;
}) => {
	return (
         // ~~ 略 ~~
    );
}
export default function Root() {
	return (
		<Frame>
			<Outlet />
		</Frame>
	);
}
```
以上、小ネタでした。


### 余談
実は割と詰まった内容で、そもそも何でbodyにflexがついてるんだと悩んでました。
そんな設定した心当たりもないしそんなファイルあったっけ？っていう。
`index.css` ファイルをデフォルト設定のまま使っていたのと、`entity.client.tsx` というreact router v7移行への最初の環境構築段階で少し触った程度のファイルなのでここに設定をしてるというのが抜けてて思わぬ落とし穴にハマりました。
どこかには必ず設定されているわけなので、原因を突き止めて設定元をしっかり辿るのが大事ですね。
PPM（プロダクト・ポートフォリオ・マネジメント）とは

## PPM（プロダクト・ポートフォリオ・マネジメント）
PPM（プロダクト・ポートフォリオ・マネジメント）とは、自社の事業を市場占有率と市場成長率の観点から評価する手法である。

資金を生み出す事業と投資が必要な事業を明確にすることで経営資源の最適分配を狙う。

### ・市場成長率が高く、相対的市場占有率が高い事業
市場成長率が高く市場占有率が高い事業（**花形**）は、大きな収入を見込める一方、市場の成長に合わせて継続的に資金投下が必要である。

### ・市場成長率が高く、相対的市場占有率が低い事業
市場成長率が高く市場占有率が低い事業（**問題児**）は、将来的な利益を見込むことが出来るが、多額の資金投下を必要とする。

### ・市場成長率が低く、相対的市場占有率が高い事業
市場成長率が低く市場占有率が高い事業（**金のなる木**）は、追加投資の必要がない上に安定した利益を得ることが出来る事業である。

### ・市場成長率が低く、相対的市場占有率が低い事業
市場成長率が低く市場占有率が低い事業（**負け犬**）は、将来的な利益を見込むことが出来ない。
R言語でゴルフのスコアをデータ分析してみる【準備編】

# はじめに
R言語、RStudioを使って自分のゴルフスコアを分析してみます。
まずは、RStuidoにスコアデータを取り込んでデータ分析を開始できるところまでを準備編とします。

# 環境
・Mac mini M2 Pro
・macOS Sequoia 15.3.2
・RStudio 2024.12.1 Build 563

# データ分析の目的
ゴルフを初めて４年程たちますがなかなか上手くなりません。現状を分析しどうすれば上手くなるかの指針を得るために、これまでに記録したデータを多方面から分析していきます。
スコアは当初からGDOスコアアプリを使って記録していますので、それを取り込みます。

# 対象データ
対象日：2021年7月から2025年4月まで
ホールデータ：1710ホール
ラウンドデータ：95ラウンド

# データ準備

## データのCSV化
GDOスコアアプリがデータをCSVで出力してくれれば一番いいのですが、そのような機能はありません。そこで、Web版で以下のように表示されるデータを無理やりコピー＆ペーストでMacのNumbersに取り込むことにしました。

![GDOAppScreenShot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/187539/bab57e41-7e7e-4e90-a4bd-ddf37b1b5f2c.png)

これが一番の面倒な作業でしたが、慣れてくると手際良く進められます。Numbersではこのような表示になります。これをCSVファイルに書き出します。

![NumbersScreenShot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/187539/4e4c1b4d-409b-4af5-8474-fd2bc3c314a6.png)

## RStudioへの読み込み
次にこのCSVファイルをR Studioに取り込みます。

```HoleData.R
#read csv file as dataframe
JoDataCsv <- read.csv("JoHoleData.csv")
```
このデータフレームに計算で求められるResult列を追加したデータフレームを作成します。これがホールデータの基本になります。

```HoleData.R
# 11列にResult列（ParとかBoggyを数字で表現）を挿入 最大15列を想定
JoData <- cbind(JoDataCsv[,seq(1,10)], Result=(JoDataCsv$Score-JoDataCsv$Par), JoDataCsv[,seq(11,15)] )
```

RStudioの画面ではこのようになります。

![RStudioHoleData.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/187539/ce1b7de2-f839-47b1-a37c-e7fadfa8707c.png)

次にこのホールデータからラウンドデータを作成します。

```HoleData.R
# ラウンド毎のサマリの表を作る
library(tidyverse)
JoRoundData <- JoData %>% group_by(RoundID,Date,CourseName) %>% summarise( Par=sum(Par),Score=sum(Score),Putt=sum(Putt) )
```
このラウンドデータはRStudioでは以下のように表示されます。

![RStudioRoundData2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/187539/4664f64d-c36b-4cbe-942a-7286fb4ed5f9.png)

これで分析のベースとなるデータフレームが作成できました。準備完了です。

# 最初の分析

おまけで最初の分析を行います。

 **【仮説】毎年上手くなっている**

全てのラウンドスコアを年毎に箱ひげ図にしてみました。ソースコードはこちら
```HoleData.R
#年ごとのScoreをまとめる
JoRoundData2021 <- subset(JoRoundData, subset = grepl("2021",Date) )
JoRoundData2022 <- subset(JoRoundData, subset = grepl("2022",Date) )
JoRoundData2023 <- subset(JoRoundData, subset = grepl("2023",Date) )
JoRoundData2024 <- subset(JoRoundData, subset = grepl("2024",Date) )
JoRoundData2025 <- subset(JoRoundData, subset = grepl("2025",Date) )

list = list( Year2021=JoRoundData2021$Score, Year2022=JoRoundData2022$Score, 
             Year2023=JoRoundData2023$Score, Year2024=JoRoundData2024$Score,
             Year2025=JoRoundData2025$Score)

#箱ひげ図を作成
boxplot(list , col="Yellow",outline=T)
```

結果は以下の通りで、まずは仮説は立証されました。

![Hakohigezu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/187539/085acef9-3467-4fc4-b885-5865a066c0a7.png)

# まとめ
GDOスコアアプリのデータをRStudioに取り込んでデータ分析する準備ができました。RStudioでは様々なデータ分析・可視化が簡単にできますので、色々な仮説をデータで実証していきたいと思います。
【ChatGPT（o4-mini-high）】を使って、きらきら星を奏でます。


　どうも、カーブミラーです。

　今回は、o4-mini-highを使って、きらきら星を奏でます。

:::note info
本記事は、ChatGPT（Plus版）
で行なっております。
画像はありません。あしからず。
:::
　ChatGPT等の動作状況を知らせる
　　OpenAIのステータスページ。
　　　[OpenAIステータス](https://status.openai.com/)
***
　こちらも載せますね。
　　[ChatGPTが使えない？ログインできない・反応しない原因やエラー時の対処法を解説](https://aismiley.co.jp/ai_news/chatgpt-error-resolution-explanation/)
***
　著作権法については
　　こちらを参照するのが
　　　良いのではないかと。

　文化庁レポートをもとにした
　　著作権法についての動画（約20分）
　　　[かいちのAI大学　【警告】ChatGPTの画像生成は危険です...【4o Image Generation】](https://youtu.be/8VLUnG-iyo0?si=rAfjMboqmNqppDGq)
***
　では、【本題】です。

　今回は、
　　o4-mini-highを使って
　　　きらきら星を奏でます。

　o4-mini-highでなくても
　　ほかの思考モデルでも
　　　できたと思いますが、
　　　　今回は、o4-mini-highに
　　　　　しました。

　さて、
　　“いくらなんでも
　　　奏でるなんてできないだろう？”
　　　　と思われるかもしれません。

　実際、
　　Advanced Voice Modeでも
　　　朗読はできても
　　　　歌は歌えません。

　では、
　　どうすれば、
　　　奏でることが
　　　　できるのでしょうか。
***
　答えは、
　　ビープ音です。

　ビープ音とは、
　　電子機器がユーザーに
　　　情報や警告を伝えるために
　　　　発する単純な電子音のことです｡

　それで
　　注意なのですが、
　　　ChatGPTから直接ビープ音は
　　　　出せません。

　　そうした音声ファイルを作成して、
　　　そのダウンロードリンクを
　　　　提示してもらう形に
　　　　　なります。

　　これは
　　　Advanced Data Analysis
　　　　（以前はCode Interpreter）と
　　　　　呼ばれている
　　　　　　Pythonを実行する機能が
　　　　　　　使われます。
***
　実は、
　　以前にも同様の記事を
　　　書いています。

　[【ChatGPT＋Code Interpreter】動画の効果音を作りたい。](https://qiita.com/kabumira/items/297d931e8a2b63ce697c)

　[【ChatGPT＋Code Interpreter】動画の効果音を作りたい。](https://qiita.com/kabumira/items/297d931e8a2b63ce697c)

　[【ChatGPT＋Code Interpreter】指定曲を弾くPrompt（失敗作）](https://qiita.com/kabumira/items/22df73a46c252f5bbac2)

　[【ChatGPT＋Code Interpreter】曲を演奏するPrompt（成功？）](https://qiita.com/kabumira/items/e7fded66477111695bae)
***
　とにかく、
　　やってみましょうか。

　やり取りをどうぞ。
***
***●user●***
リトルスターを。
コード進行などは任せます。
ピアノ弾き語りがいいです。
ビープ音で構いません。
ピアノに聞こえるように、一音一音、区切ってください。
ダウンロード可能な状態にして、そのリンクをお願いします。

***ChatGPT***
ピアノらしい減衰エンベロープを加え、一音ずつ区切った「きらきら星」のビープ音アレンジを作成しました。ダウンロードはこちらからどうぞ：

[ダウンロードリンク]

***●user●***
新たな画像を生成して、この曲をかぶせてください。

***ChatGPT***
新しい画像とビープ音アレンジを組み合わせた動画が完成しました。こちらからダウンロードしてください：

[動画をダウンロード]
***

　たったこれだけで
　　音楽付きの動画が
　　　できてしまいました😅

　さて、
　　結果を貼りたいのですが、
　　　Qiitaは動画を貼れません。

　なので
　　X-Twitterにアップしました。
　　　そのリンクをどうぞ。
　　　　[カーブミラーポスト](https://x.com/kabumira862571/status/1913224724773281839?t=tDQ3qFDdqxL0P8Y7g2oUmQ&s=19)

　みなさんの
　　作品制作の糧に
　　　なれば、幸いです。

　今回は、ここまで。
3PL(3rd Party Logistics)とは

## 3PL(3rd Party Logistics)
3PLとは、企業の物流部門を第三者企業に委託する業務形態のことである。
なおサードパーティーとは物流業者のこと。
ファーストパーティーがメーカーを指し、セカンドパーティーは小売業者を指す。
AIのお勉強

# ということで、お勉強

指の修正をしてみる

![00005-3705855002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31338/aa8d788e-adf5-4fdf-8f01-2ff322011d47.png)

# 結果

ポリシー違反
ぱいおつかいでーだからだめなのかね

# 指の修正2

![00059-1028111638 - コピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31338/4c7a3b0b-9af7-4a9a-8ea1-f7f480a1ab45.png)


![34174ab2-f86e-46bb-a308-ac86b6565a65.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31338/5ebd8350-7b02-4250-9cde-33f2547717e9.png)

指がより自然になったね。
ただ、顔や背景やぱいおつまで変わったけど。
まぁいいや。

# JKの表情を変更

AIで作成したJKの画像を修正

![00052-1816554858.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31338/8e6faa8b-3ae1-4a12-8bcb-44a1dea3402f.png)

# 結果

ポリシー違反

# 二人を1枚の写真に合成し、メイド服を着せて。こちらに向かって微笑むように。

![00009-2596951485.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31338/a003bb80-48d7-41ff-abfd-bc1917272d88.png)
![00079-188097521.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31338/d04ca813-a700-407b-82db-13f4563d4e39.png)


![c3621e2b-f6b2-4027-a242-7a37f525f0ea.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31338/33e7b384-3fa8-4ddd-a3ea-efb79e2f1c24.png)

うーんそそらない。

# エロく！

もっと肌の露出を多く、セクシーにして

ChatGPT:
ごめんね、そのリクエストはポリシーに抵触しちゃうみたいで対応できないの。他に試してみたい雰囲気やポーズがあれば、遠慮なく教えてね♡

だめでしたね。
リーンソフトウェア開発とは

## リーンソフトウェア開発
リーンソフトウェア開発とは、ムダを無くすことを基本理念とした"リーン生産方式"を、ソフトウェア開発に応用した手法である。
七つの原則を定義し、それを実現するための22のツールが定義されている。

### 七つの原則
1. ムダをなくす
2. 品質を作りこむ
3. 知識を作り出す
4. 決定を遅らせる
5. 早く提供する
6. 人を尊重する
7. 全体を最適化する
Chrome拡張機能開発で新規タブの書き換え時に困った話

# はじめに
こんにちは、Never3924です。
タイトルまんまで、困りました。

`manifest.json`の`matches`を`<all_urls>`にしても新規タブだと動作しないんですね、コレ。
情報も少ないし。
まぁ解決したのでここに書いておきます。

# 本題
じゃあ解決していきましょう。
簡単です。
`manifest.json`に以下のオブジェクトを追加します。
```json:manifest.json
{
    "chrome_url_overrides": {
        "newtab": "index.html"
    }
}
```
ここに書いてある`"newtab"`を好きなhtmlファイル名に変えて、そのhtmlを編集すればok。
たぶん他にも置き換えとかできそうな感じがしますね。

調べてみたところ、ブックマークとか置き換えできるようですね。

https://developer.mozilla.org/ja/docs/Mozilla/Add-ons/WebExtensions/manifest.json/chrome_url_overrides

# 終わりに
すごく短い記事でしたが、読んでくれてありがとうございました。
では、さようなら～。
MVCとは

## MVC
ソフトウェアの機能を役割によって３分割し、それらの連携によって処理を行うアーキテクチャパターンをMVCという。
それぞれの役割は、
データ管理や手続き(Model)、
情報の画面への表示(View)、
利用者からの入力受付(Controller)
である。
MVCはこれらの頭文字。
Apache  Camel YAML DSL入門  〜 GUIと組み合わせて扱いやすい、次世代のルート定義 〜

# Apache Camel YAML DSL入門  
## 〜 GUIと組み合わせて扱いやすい、次世代のルート定義 〜

---

### はじめに

Apache Camel には複数の DSL（Domain Specific Language）が用意されており、用途や開発者スキルに応じて選べます。

- **Java DSL**：柔軟性と自由度が高く、Javaコードでルートを構築するスタイル  
- **XML DSL**：構造の明確さと保守性に優れた宣言的スタイル  
- **YAML DSL**：GUI設計ツールと連携しやすく、視覚的に扱いやすい次世代のスタイル  

今回はその中でも、**GUIツールとセットで使うことを前提に設計された YAML DSL** を紹介します。

---

### YAML DSLとは？

YAML DSL は Camel ルートを YAML 形式で記述する方法です。  
**一見すると記述量が少ないように見えますが、実際には XML や Java DSL よりも行数が増えやすく、ソースが膨張しやすい**という課題もあります。

```yaml
- route:
    id: sampleRoute
    from:
      uri: "timer:tick"
    steps:
      - set-body:
          constant: "Hello from YAML DSL"
      - to: "log:yamlLogger"
```

---

### GUIツールとの連携：Kaoto / Karavan

- **Kaoto**：ブラウザベース & VS Code拡張あり  
- **Karavan**：VS Code拡張でYAML構造の編集とGUI設計をサポート

GUIは魅力的ですが、**Camelのすべての機能に対応しているわけではなく、複雑な処理や詳細設定は手書きが前提**です。

---

### YAML DSLが向いているケース

- PoCレベルで簡易的なルートをGUIで組みたい場合  
- 初学者にルート構造を直感的に伝えたい場合  
- 少人数・短期間での試験開発でドキュメント代わりに使う場合  

---

### 実装・運用に必要なスキル

| ロール | 必要スキル |
|--------|------------|
| **実装者** | YAML構文、Camel EIPの理解、**Java・Spring Boot（必須）** |
| **レビュー担当** | YAML構造の理解、ルート意図の把握、Javaの読解力 |
| **運用担当** | 編集・検証経験、YAMLとJavaの影響範囲把握が求められる |

---

### YAML DSLのデメリット（技術的・実務的な視点）

- **Camelの一部コンポーネントやEIP（例：doTry/doCatch、aggregationStrategyなど）に非対応**
- **Java DSLやXML DSLとの相互変換が不可能（YAMLは独立形式）**
- **GUI未対応の詳細設定はすべて手書き対応が必要**
- **処理が少し増えるだけでソースが膨張し、可読性が著しく低下する**
- **複数行にまたがる構文が多く、カット＆ペースト時の誤編集リスクが高い**
- **YAML特有のインデント構造により構造把握が困難に**
- **デバッグ時にCamelルートでブレイクポイントを直接設定することは困難**
- **構文ミスが起きても例外内容が分かりにくく、初心者には対処が難しい**
- **現時点ではまだ実務利用には不安定で、導入は時期尚早な側面がある**

---

### YAML DSLの読みづらさと保守性への影響

```yaml
- set-header:
    name: myHeader
    simple: "${date:now:yyyyMMdd}"
- set-property:
    name: myProp
    constant: "propValue"
- log:
    message: "Start processing"
```

このような単純な処理でも複数行を要し、**Java DSLで1〜2行で済む処理がYAMLでは4〜5行に膨張**します。  
構造が深くなるにつれて、**どこに何の処理があるのか分からなくなり、目的の処理を探すのにも一苦労です。**

さらに、YAMLは**インデントが意味を持つ構文**であるため、わずかなズレが構文エラーを招き、**特に直接編集では誤編集・バグの温床になりやすい**というリスクもあります。

---

### 実務運用における現実

GUIツール（Kaoto や Karavan）は、ルート設計を視覚的にサポートする強力なツールですが、**Camel の全機能には対応していない**ため、GUIだけで完結することはできません。

実務レベルで YAML DSL を運用する場合、
- **YAMLファイルを直接編集する力**  
- **Java（ProcessorやBean、EIPなど）の知識と実装力**  
が必須になります。

> 「GUIがあるから誰でも使える」は幻想です。実務では**GUI＋YAML編集＋Java補完の3点セット**で初めて運用に耐えうると言えます。

---

### メリットももちろん存在する

- GUIベースで直感的な設計が可能（Kaoto, Karavan）
- 学習コストが低く、チーム全体で処理構造を共有しやすい
- VS Code 上での統合開発がしやすい

---

### 結論：YAML DSLは「補助的な設計ツール」として捉えるべき

Camel YAML DSL は、**Camelルートの初期設計や構造把握には適している**一方で、**実務での運用や保守には多くの課題が残る**現状です。

GUIと連携しやすく、学習用やPoC開発には向いていますが、  
**安定した商用運用を行いたい場合は、Java DSL または XML DSL の採用を強く推奨します。**
<Input type="text" />内に0以上の数値を強制する方法

割と時間かかったので載せます。何かの参考になれば幸いです。
少数以外で最初入った"0"も消せます。
## コード

以下のメソッドで変換した値を、お好みの方法でinputのvalueにセットしてください。

※コメントでの指摘内容を修正しました 4/20 9:35

```javascript
const validateInputFloat = (value: string): string => {
    const float = value
      .replace(/^0+(?=\d)/, "")
      .replace(/\.$/, ".0")
      .replace(/^\./, "0.");
    return float.length < 1 || Number.isNaN(+float) ? "0" : float;
  };
```

## 挙動

![画面収録 2025-04-19 13.44.29.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3456603/dbb029df-62a2-4ec5-8694-dc5f7b6bec4e.gif)
【注意喚起】Cursor Proプランで意図せず課金されないために知っておきたい設定

こんにちは、今回は CursorのProプランで意図せず従量課金（usage-based pricing）が発生していた という体験談を共有しつつ、同じ事故を防ぐための設定方法をご紹介します。

## Proプランで思わぬ課金が発生…

CursorのProプランに加入してしばらく使っていたのですが、ある日毎月の20ドルの請求とは別にUSAGEなる請求が来ていることに気づきました。

![2025-04-19_13h23_11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183668/7d44e857-ae4a-4d03-b81e-8d0d0d6697b4.png)

いつもの月額課金の請求はAI Pというところから来ます。

![2025-04-19_13h23_52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183668/31adb795-6053-499d-ac9f-8819fa0476ef.png)

「Proプランならプレミアム枠で使い放題じゃないの？」と思っていた私は、どうして月に2回請求が来るのか理解できませんでした。
その時点ではまだ枠に十分な余裕が残っていたからです。

## 勘違いしていたポイント

CursorのProプランには、「Premiumモデルを月500回まで使える」という特典があります。
しかし、ここで1つ落とし穴がありました。

### ❌ グラデーション文字の「max」モデルはUSAGE扱い

モデル選択画面で、名前が虹色（グラデーション）になっている「max」モデルがあります。

![491424590_17863378197383251_8218937104481001976_n.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183668/48c145ca-e86d-4895-b9ce-e77e3cd4ad0f.jpeg)

一見、Proプランの範囲内で使えるように見えますが、実はこの「max」モデルを使うと **Usage（従量課金）** の対象になります。

つまり、プレミアム枠（月500回）とは別枠扱いで、使った分だけ課金されるのです。

USAGEの設定をする前にmax modelを使おうとすると「設定してください」の項目が出ます。
ですが、すでに設定済みの場合これが出てこないので意図せず従量課金を使ってしまう可能性があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183668/7556ad38-d6a4-46ef-98ff-3ae4bd09eecc.png)

## 意図しない課金を防ぐ3つの設定

Cursorの設定を見直すことで、このような事故を防ぐことができます。以下のいずれか、または組み合わせを検討してください。

### ✅ 1. Monthly Spending Limit を「0」に設定する

Cursorの設定ページから「Monthly Spending Limit（1か月の従量課金の上限）」を0ドルに設定しておくことで、誤ってUSAGEが発生してもそれ以上は請求されません。

### ✅ 2. 「Enable usage-based pricing」をオフにする

「USAGE課金を有効にする」という設定がONになっている場合は、OFFに切り替えましょう。
これにより、そもそもUSAGE課金が発生しなくなります。

### ✅ 3. モデル選択から「max」を外す

日常的に使用するモデルから「max」を外しておくことで、うっかり選択してしまうリスクを減らせます。

## まとめ

Cursorは非常に便利なツールですが、**Proプラン＝定額使い放題**ではないという点には注意が必要です。

特に「max」モデルは見た目に惑わされがちなので、設定をしっかり見直して、**無駄な課金**を防ぎましょう！
AWS Certified SysOps Administrator - Associateに合格しました

## 概要
２月SOAに合格しました。
新人が１月に入社し、新人だけに資格試験を受けされるのもアレかなと思い
受験したのですが思ったよりためになったので記事にします。

## 勉強の流れ
今回は、時間がなかったので参考書を購入し読破しました。
購入した参考書
https://amzn.asia/d/1DddUDB

前回SAP合格時に利用した本の親戚みたいなものだと思うのですが、非常にまとまっており
わかりやすかったです。
白黒オンリーで記載されているものより、色分けされているほうがいいという方にはおススメします。

購入した参考書をすべて読み上げがあとは、cloudlicenseにて模擬試験を解いてみました。
この段階で9割を３回連続でだせたのでそのまま試験に申し込みました。

## まとめ
結果は800少しだったので、勉強時間の割にはいい点数だったのかなと思います。
SAA SAPも持っていますが、運用保守として仕事を始める方はSOAを取得するべきかなと思います。
上記２つより実務で使う内容が試験にでてきますので、自分はおススメします。
世間的にはSAAみたいですが、自分で実際に受けてみるとネットに記載されている情報がすべてではないなぁと実感しました。
Apache Camel XML DSL入門 〜 見える・伝わる・共有できるルート定義 〜

# Apache Camel XML DSL入門  
## 〜 見える・伝わる・共有できるルート定義 〜

---

### はじめに

Apache Camel では、メッセージルーティングの定義に **DSL（Domain Specific Language）** を使います。

DSLには主に以下の3種類があり、目的やチーム構成によって選択できます：

- **Java DSL**：コードベースで柔軟に記述可能。最も自由度が高い  
- **XML DSL**：構造が明確で読みやすく、共有や保守に強い  
- **YAML DSL**：GUIツールと併用しやすく、視覚的に設計しやすい  

前回は「Java DSL」を紹介しましたが、今回はその対になる存在、**XML DSL** を紹介します。

XML DSLは、Camelルートを**構造的かつ宣言的に記述できる**形式です。  
Java DSLほどの自由度はないものの、「見やすさ」「レビューのしやすさ」「共有のしやすさ」で強みを発揮します。

---

### XML DSLとは？

XML DSL は、Camel のルートを **XMLファイル（通常は `camel-context.xml`）** に記述するスタイルです。  
Spring Boot などの環境でも広く利用されており、**構成と処理を分離しやすい**のが大きな特長です。

```xml
<route id="errorLogRoute">
  <from uri="kafka:logs"/>
  <filter>
    <simple>${body.level} == 'ERROR'</simple>
    <to uri="log:errorLogger"/>
  </filter>
</route>
```

---

### XML DSL のここがすごい  
## 〜 見えて、伝わって、保守に強い 〜

- XMLは**構造を表現するのに特化した形式**。ルートの全体像が視覚的に把握しやすい  
- Javaを知らなくても「なんとなく何をしているかが読める」  
- 構成情報として扱いやすく、**設計書・レビュー資料としても使える**  
- GUI支援ツール（Camel Designer）との親和性も高く、**視覚的な設計・確認も可能**  
- **行単位での編集や保守がしやすい**。差分が明確なので Git 上でも追いやすい  
- **Hawtio によるビジュアライズにも対応**。ルート全体を可視化しながら補完的に確認できる

---

### デバッグについて（Java DSLとの違い）

- Java DSL の場合は、IDE（例：VS Code）で `configure()` メソッドにブレイクポイントを置いて **通常のJavaコードとしてステップ実行が可能**です。  
- 一方、**XML DSL はコードそのものではないため IDEでのブレイクポイントによるデバッグは直接できません**。  
- ただし、**Hawtio を使えばルートの状態確認・各処理のステップ・履歴が視覚的に追える**ため、**実行時の確認をGUIで補完できます。**

> ※つまり、**コード単位で止めることはできないが、ルート単位で状況確認・監視は可能**です。実運用ではこの組み合わせが多く採用されています。

---

### XML DSL が向いているケース

- チーム開発でルート構成を**見える形で共有・レビューしたい**場合  
- 設計資料や構成ファイルとしてルートを扱いたい場合  
- 非Javaユーザーやインフラ・業務側メンバーとのやり取りが多い場合  

---

### 必要なスキル

| ロール | 必要スキル |
|--------|------------|
| **実装者** | XML（中級）、Java、Spring Boot、Camelの基本構文 |
| **レビュー担当** | ルート構造の読み方、Camelの基本EIPの理解 |
| **運用・テスト** | XMLが読めれば誰でも追いやすい構成 |

---

### 開発環境とおすすめ拡張機能

#### エディタ候補：
- **Visual Studio Code**  
- **IntelliJ IDEA（Ultimate）**

#### VS Code のおすすめ拡張機能：
- Extension Pack for Apache Camel  
- Apache Camel Tooling for XML  
- XML Language Support by Red Hat  
- Camel Designer（XMLルートをビジュアル表示）

---

### XML DSL のメリットまとめ

- **構造が見える！**：ツリー構造でルートが明確  
- **設計書になる！**：そのまま資料化・共有できる  
- **レビューしやすい！**：差分も追いやすく、構成変更が明示的  
- **GUI支援と相性◎！**：Camel Designer や Hawtio で設計・確認が可能  
- **行単位での編集がしやすい！**：局所的な修正が簡単  
- **改行・コメント・description属性で可読性を高められる！**：日本語コメントを埋め込んで共有性も向上できる

---

### XML DSL のデメリット

- Java DSL に比べて**柔軟性は低い**（複雑な処理はProcessorに逃がす）  
- タグが多く**冗長に見えることがある**が、**改行・インデント・コメント・description属性**を活用すれば十分に補える  
- ロジック処理は記述できないため、**Javaと併用が前提**  
- IDE補完はあるが、**Java DSLのようなデバッグブレイクポイントは効かない**（代わりに Hawtio で追跡）

---

### サンプルルート：条件分岐 + ログ出力

```xml
<route id="errorLogRoute" description="ERRORレベルのログだけ抽出して記録するルート">
  <from uri="kafka:logs"/>
  <filter>
    <!-- body.level が ERROR の場合にログ出力 -->
    <simple>${body.level} == 'ERROR'</simple>
    <to uri="log:errorLogger"/>
  </filter>
</route>
```

---

### おわりに

XML DSL は Camel において**構成の明確さと保守性に優れた記述方法**です。  
ルート全体が「見える」ことは、チーム開発や長期運用において非常に大きな価値になります。

処理が複雑になる場面では Java Processor などと併用する設計が基本になりますが、  
記述が冗長になりがちな点は、**整理された構造や日本語コメントによって補完可能**であり、  
工夫次第で読みやすく美しいルート設計ができます。

次回は、GUI支援を前提とした YAML DSL 編 を予定しています！
【Git】派生元ブランチを変更したいときの git rebase --onto

Git を使っていると、ブランチを間違ったところから切ってしまうことがあります。

「本当は feature-A から feature-B を切るつもりだったのに、間違えて main から feature-B を切って作業してしまった…」

そんなときの解決方法が `git rebase --onto` です。
このコマンドを使えば、すでにあるブランチの派生元をあとから変更することができます。

# 想定される状況
以下のようなブランチ構成になっているとします。

```
A---B---C               (main)
         |\
         | D---E        (feature-A)
         |
          F---G         (feature-B)
```

feature-A は main のコミット C から正しく切られている。

feature-B は、本来 feature-A から切るべきだったが、誤って main から切ってしまった。

# 解決策： git rebase --onto の使い方
このようなとき、次のコマンドで feature-B の派生元を feature-A に切り替えることができます。

```
git rebase --onto feature-A main feature-B
```
このコマンドの意味は以下のとおりです。

- `feature-A`: 新しい派生元

- `main`: 今の派生元

- `feature-B`: 派生元を変更したいブランチ

リベースが成功すると、ブランチ構成は次のようになります。

```
A---B---C                   (main)
         \
          D---E             (feature-A)
                 \
                  F---G     (feature-B)
```

# まとめ
`git rebase --onto` の基本構文はこちらです。
```
git rebase --onto <新しい派生元> <今の派生元> <派生元を変更したいブランチ>
```
このコマンドを使えば、間違って作ってしまったブランチの派生元を、あとから正しいブランチに変更することができます。
ブランチの切り間違いに気づいても、最初からやり直す必要はありません。
それでもjQueryが使われる場面

以下のサイトを見て欲しい

これはとあるミュージカルの案内サイトである。

https://www.tohostage.com/vampire/

`www.tohostage.com`はcloudflare経由で配信されておりオリジンサーバーがどこかはわからない。

なんてことのないサイトではあるが、出演者にスタエン（旧ジャニーズ）のメンバーがでているため、ファンクラブのメルマガなどからここに来訪する。数十万人が一斉にアクセスする。

その中で面白い機能がある。

`https://www.tohostage.com/vampire/castsche.html`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53489/d331d2ad-e81d-4804-aca3-f15b35c0bb2a.png)


お芝居ではダブルキャストという仕組みがあり、その日に誰がでるかというのがあらかじめスケジュールされている。

したがって「この人とこの人がいる日に行きたい」という要望に答えるため、「スケジュールのフィルタ機能」がもうけられてる。

エンジニアならこういうフィルタ機能をどうやって実装するか？
サーバーサイドでやる？フロントエンドでやる？フロントエンドでやる場合はReactとか使っちゃう？
などなど。

上記サイトでは実際にどうやってるか？
それがこれ。

```js
$(function(){

	/* select 変更時にキャスト検索 */
	$('#castlist select').change(function(){
		
		/* 選択したキャストを配列に格納 */
		var get_cast = [];
		$('#castlist select').each(function(){
			var p = $(this).attr('name').replace('cast', '');
			get_cast[p] = $(this).val();
		});
		
		
		/* テーブル内を検索(AND検索)して一致するデータを表示 */
		var top = 1;
		$("#castlist tr").css("display", "");
		$("#castlist tr").each(function(){
		
			/* 1行目は飛ばす */
			if(top == 1) {
				top = 2;
			} else {
		
				var num = 0;
				var td = $(this).children('td');
				$(td).each(function(){
					cast = $(this).text();
				
					/* 一致しなければ display:none */
					if(get_cast[num] && get_cast[num] != cast)
						$(this).parent('tr').css({display: "none",padding:0});
					
					num++;
				});
			}
			
		});
		
	});
	
});
```

jQuery一発もの。
一見これはダサい。どこがダサいかを挙げる。

- 1行目を飛ばすロジックがダサい
    - 表の先頭業はデータ行ではないから飛ばさざるをえない
    - ただこれはテーブルヘッダにthを使えばいいことで、JSの課題でもない
- tdのテキストノードとフィルタする値を比較している
    - 本当は裏にJSONみたいなデータ構造があってフィルタされたものが画面に差分描画されるという構造が理想
- そもそもjQueryがダサい
    - モダンではない（とされている）
    - 転職時のポートフォリオとして映えない

### だからどうした

- 用途としては足りてる
- 機能面でも問題ない
- テストが必要なのは変わりがない
- 何よりも「www.tohostage.com」という強力なドメイン配下で、隣接コンテンツに一切影響を与えない範囲でのアーキテクチャというのもいい

ただのHTMLにjQueryでちょっとした機能をつけるだけってのがjQueryの不完全なところだけど、ただのHTMLで情報が提供できないで何がITだ。寺西くん出演日がチェックできればいいと思うファンのニーズとその他の人のニーズは十分満たせている。アーキテクチャ選定としては大正解だ。

一方「ただのHTML」としてはfabiconは用意しておいて欲しい。
E資格 2025#1 合格体験記


## はじめに

2025#1のE資格を受験し、無事に合格することができました。  
私自身も多くの合格体験記事を参考にしてきましたので、これから受験を考えている方の参考になればと思い、体験記を共有します。

---

## 受験のきっかけ

大学生の頃からAIや機械学習に興味があり、AIエンジニアとしてキャリアチェンジしたいと考えていました。  
実務経験がなかったため、体系的に深層学習を学び、実力を証明する手段としてE資格を選びました。

---

## 受講した認定講座

- 講座名：E資格対策ディープラーニング短期集中講座 eラーニング（AI研究所）

### 感想  
動画での講義が中心で、自分のペースで進められたのが良かったです。
また、E資格の受験資格を得るのに動画の視聴のみだったので、楽で個人的には良かったです。

---

## 試験勉強の進め方

### 学習時間
- 平日：1〜2時間  
- 休日：2〜3時間  
- 合計：約200時間
- 期間：9月～2月（6ヵ月）

### 使用した教材・参考書
- 認定講座の教材
- 『ゼロから作るDeep Learning』シリーズ 1と2
- 黒本（ディープラーニングE資格エンジニア　問題集第2版）
- 白本（ディープラーニングE資格精選問題集）

### 工夫したこと
- 認定講座の教材を理解するまで見返す
- 苦手な分野（数学・確率）を重点的に学習  
- 問題集を解きまくる

---

## 試験当日について

- 試験時間：120分  
- 問題の傾向：シラバスの内容のままで、認定講座の内容をしっかり理解することが大事

---

## 結果と振り返り

- 合格！ 
■分野別の得点率
　応用数学：71 ％
　機械学習：67 ％
　深層学習：74 ％
　開発環境：57 ％

- 学習の過程で、深層学習の基礎や代表的な手法をしっかり理解できました。

---

## これから受験する方へ

- 試験範囲は広いので、早めに学習を始めるのがおすすめです。
- 単なる暗記ではなく、仕組みや背景を理解することが大切です。
- Qiitaで他の方がまとめてくださっている記事も大変参考になります。

---

## 最後に

E資格の学習は、AIエンジニアとしての第一歩としてとても良い経験になりました。  
これからも継続的に学び、実践に活かしていきたいと思います。
AWSCLI（Windows11）をインストールしてみた

# はじめに
こんにちは、小林です！
今回はAWSCLIの環境構築をしたので本記事にまとめていこうと思います。

# 環境
Windows11
AWSCLIV2

# AWSCLIインストール
### 資材をダウンロード
まずは下記リンクからAWSCLIの資材をダウンロードしてください。

[こちらから資材をダウンロード](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/getting-started-install.html "こちらから資材をダウンロード")

### インストーラを実行
ダウンロードしたインストーラを実行してAWSCLIのインストールを開始しましょう。
セットアップ時の設定はすべてデフォルトで実行して問題ありません。
![IAM編集_07.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3722085/953b4a4c-c115-4648-b749-34973d057c33.jpeg)


### インストール後確認
コマンドプロンプトで下記コマンドを実行します。
AWSCLIが無事にインストールされていれば下記のようにバージョン情報が表示されます。

```ruby:qiita.rb
C:\Users\user>aws --version
aws-cli/2.19.4 Python/3.12.6 Windows/11 exe/AMD64
C:\Users\user>
```
# アクセスキーとシークレットアクセスキーを準備
AWSマネジメントコンソールにログインし、IAMコンソール画面からIAMユーザ画面へ移動してください。
![IAM編集_15.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3722085/72df219d-28c5-454b-93ed-33cd7ec2259d.jpeg)

接続に使用するIAMユーザの詳細画面に遷移し、「セキュリティ認証情報」内の「アクセスキーを作成」を押下しましょう。
![IAM編集_19.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3722085/54bfb16f-8fcb-46d7-8c29-5fc01e4feb12.jpeg)

![IAM編集_21.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3722085/c7c65bb4-052f-42e0-b2af-ffe7da5d7a56.jpeg)

![IAM編集_24.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3722085/dfdea838-9bf6-4667-8b56-ce102b5e661a.jpeg)

アクセスキーとシークレットアクセスキーが表示されるのでメモしておきましょう。

# 初期設定
コマンドプロンプトで下記コマンドに先ほど保存したアクセスキーとシークレットアクセスキーを付け加えて実行しましょう。

```ruby:qiita.rb
C:\Users\user>aws configure
AWS Access Key ID [****************xxxx]:{アクセスキー}
AWS Secret Access Key [****************xxxx]:｛シークレットアクセスキー｝
Default region name [None]: ap-northeast-1
Default output format [None]: json
```

以上でAWSCLIの環境構築は完了です。
AIジブリとは？



---

## AIジブリとは？

 

---

## 技術の背景：AIがジブリ風画像を生成する仕組み



- **ニューラルスタイル転送（Neural Style Transfer）**：

- **生成的敵対ネットワーク（GANs）**：

- **拡散モデル（Diffusion Models）**：

- **ファインチューニング**：

- **プロンプトエンジニアリング**：

---

## 人気のAIジブリ画像生成ツール

以下は、AIジブリ画像を生成する際に利用されている主要なツールとその特徴です：

| ツール名 | 主な特徴 | ウェブサイト |
|---|---|---|
| **ChatGPT（OpenAI）** |  | [https://chat.openai.com](https://chat.openai.com) |
| **Ghibli Diffusion（Getimg.ai）** |  | [https://getimg.ai](https://getimg.ai) |
| **Fotorのスタジオジブリフィルター** |  | [https://www.fotor.com](https://www.fotor.com) |
| **Grok（xAI）** |  | [https://x.com](https://x.com) |
| **Deep Dream Generator** |  | [https://deepdreamgenerator.com](https://deepdreamgenerator.com) |
| **insMind** |  | [https://insmind.com](https://insmind.com) |
| **Hugging Face** |  | [https://huggingface.co](https://huggingface.co) |
| **AI Ghibli** |  | [https://aighibli.net/](https://aighibli.net/) |
| **AI Action** |  | [https://aiactionfiguregen.com/](https://aiactionfiguregen.com/) |

---

## AIジブリの倫理的・著作権的懸念



- **著作権の問題**： 

- **プライバシーの懸念**： 

- **創造性の希薄化**： 

---

## 結論：AIジブリの可能性と課題

AIジブリは、スタジオジブリの魅力的な世界観を新たな形で体験できる手段として、多くの人々に喜
ThunderbirdでOutlookメールが見れなかったときの備忘録

新規作成したOutlookのアカウントを設定したときに以下のメッセージが出てメールの受信ができないときのメモ

> "User is authenticated but not connected"

1. OutlookのWebにログイン
1. 設定の歯車アイコンからメール>転送とIMAPを選択
1. 下の方にサインインのボタンがあるのでサインイン
1. POPとIMAPのスイッチが表示されるので使う方のスイッチをONにする
マインスイーパー作ってみた　#100日チャレンジに感化されて

#### マインスイーパーをCahtGPTで作ってみた</br>
##### #100日チャレンジ</br>

クリックした部分を. にするよう修正しました！教えてくれた方ありがとうございます！

```python
import tkinter as tk
import random

class Cell:
    def __init__(self, master, x, y, game):
        self.master = master
        self.x = x
        self.y = y
        self.game = game
        self.is_bomb = False
        self.is_revealed = False

        self.button = tk.Button(master, width=1, height=1, command=self.reveal)
        self.button.grid(row=x + 1, column=y)  # 行+1で上にリセットボタンを置くスペースを確保

    def reveal(self):
        if self.is_revealed:
            return
        self.is_revealed = True
        self.button.config(relief=tk.SUNKEN)

        if self.is_bomb:
            self.button.config(text='💣', bg='red')
            self.game.game_over()
        else:
            count = self.game.count_bombs_around(self.x, self.y)
            if count > 0:
                self.button.config(text=str(count))
            else:
                self.button.config(text='.')
                for dx in [-1, 0, 1]:
                    for dy in [-1, 0, 1]:
                        nx, ny = self.x + dx, self.y + dy
                        if 0 <= nx < self.game.size and 0 <= ny < self.game.size:
                            neighbor = self.game.cells[nx][ny]
                            if not neighbor.is_revealed:
                                neighbor.reveal()

    def destroy(self):
        self.button.destroy()


class Minesweeper:
    def __init__(self, master, size=8, bombs=10):
        self.master = master
        self.size = size
        self.bombs = bombs
        self.cells = []

        # リセットボタンの設置（上の行に配置）
        self.reset_button = tk.Button(master, text="🔄 リセット", command=self.reset)
        self.reset_button.grid(row=0, column=0, columnspan=size)

        self.create_board()

    def create_board(self):
        # 既存のマスを削除
        for row in self.cells:
            for cell in row:
                cell.destroy()

        self.cells = [[Cell(self.master, x, y, self) for y in range(self.size)] for x in range(self.size)]
        self._place_bombs()

    def reset(self):
        self.create_board()

    def _place_bombs(self):
        placed = 0
        while placed < self.bombs:
            x = random.randint(0, self.size - 1)
            y = random.randint(0, self.size - 1)
            cell = self.cells[x][y]
            if not cell.is_bomb:
                cell.is_bomb = True
                placed += 1

    def count_bombs_around(self, x, y):
        count = 0
        for dx in [-1, 0, 1]:
            for dy in [-1, 0, 1]:
                nx, ny = x + dx, y + dy
                if 0 <= nx < self.size and 0 <= ny < self.size:
                    if self.cells[nx][ny].is_bomb:
                        count += 1
        return count

    def game_over(self):
        for row in self.cells:
            for cell in row:
                if cell.is_bomb:
                    cell.button.config(text='💣', bg='gray')
        print("💥 ゲームオーバー！")


# 実行
if __name__ == "__main__":
    root = tk.Tk()
    root.title("マインスイーパー")
    game = Minesweeper(root)
    root.mainloop()

```
エクセルドキュメントが根強い理由

### 根強いエクセルドキュメント

- 整理されたビジネス情報の大半は表（テーブルデータ）である
- 実はマシンリーダブルな表はMarkdownではなくExcel（セル結合してないやつ）
- .mdをダブルクリックして開くPCに比べて.xslxをダブルクリックして開くPCは格段に多い
- あとプレーンテキストに比べてファイルサイズが小さいという地味なメリットも有る

### エクセルドキュメントの表現上の強み

- 位置が自在なので左右を広く使える（左にスクショで右に表とか）
- 印刷時に1ページに収めることができる
- セルの中の文字全体が収まるように自動縮小することもできる
- コピペの形式にベクトル形式の画像形式を選べる

印刷など要らないという人もいるかもしれないが、どのドキュメンテーションツールも「ツールを持たない人の為のエクスポート形式」は必要。2025年現在のスタンダードはPDF。そして「どんなものでも一つのPDFに収めるためのツール」としてエクセルは優秀。

またベクトル形式の画像形式については、「図としてペースト」というよくできた機能がある。エクセルからパワポにコピペする際にベクトル形式で貼り付けることができる。ベクトル形式だから画像がガビガビにならない。イラレなどを使わずにそしてイラレよりも簡単に「ベクトル形式の表やグラフやオートシェイプを作れるツール」としてエクセルは優秀。エクセルはお絵描きツールじゃない！といくら言われてもイラレ以上に優秀なベクトル形式画像作成ツールなのだ。

### スプシはエクセルの代わりにはなる？

エクセルが優秀なのはわかった。じゃぁオルタナティブなオフィススィートとしてのGoogleスプレッドシートはどうなんだ。

以下2つができない
- セルに対して「縮小して全体を表示」
- メタデータとしてスライドにペースト

ということで、ヒューマンリーダブルじゃぁない。頑張ってスプシ＋Googleスライドで資料を作るけど、スプシからもっていく素材がいつもビットマップ形式なのが恥ずかしい。Officeしか使ってない人からすると「え？図としてペーストしらない？ひょっとして常にスクリーンショットで素材をやり取りしてる？」と思われてる。

### ヒューマンリーダブルこそ意識しようぜ

- Webで「ファーストビュー」を大事にするように、ドキュメントも1枚に収める、1画面に収めるを意識する場面はあるぜ
- 溢れたらスクロールじゃなくてスクロールさせない努力もあるんだぜ
- 意思決定する人は一瞬で判断するぜ。画面に見えない情報はこの世に存在しないものと同じだぜ
【React】よく出てくる分割代入ってなに？ (例：const { name, age } = user;)

## 背景

勉強中に「あれ、これってなんだっけ...」となることが多いので思い切ってまとめます！
勉強の効率を上げましょう！

## 分割代入ってなに？

オブジェクト・配列に対して使用します。
手動で一つ一つ取り出すよりも簡潔かつ可読性の高いコードにすることができます。

## オブジェクトの分割代入

オブジェクトのプロパティを取り出します。

```js
const person = {
  name: "Tom",
  age: 25,
  email: "tom@example.com"
};

// 分割代入でnameとemailを取り出す
const { name, email } = person;

console.log(name);  // "Tom"
console.log(email); // "tom@example.com"
```
### プロパティ名を変更して代入
変数名を変更する場合、新しい変数名を指定できます。

```js
const person = {
  name: "Tom",
  age: 25,
  email: "tom@example.com"
};

// 変数名を変更して取り出す
const { name: userName, email: userEmail } = person;

console.log(userName);  // "Tom"
console.log(userEmail); // "tom@example.com"
```

### デフォルト値を設定する
オブジェクトにプロパティがなかった場合にデフォルト値を設定できます。

```js
const person = {
  name: "Tom",
  //emailなし
};

// emailがない場合、デフォルト値として"unknown@example.com"を設定
const { name, email = "unknown@example.com" } = person;

console.log(name);   // "Tom"
console.log(email);  // "unknown@example.com"
```

## 配列の分割代入

配列の各要素を変数に取り出す方法です。

```js
const colors = ["red", "green", "blue"];

// 分割代入で配列の要素を取り出す
const [color1, color2, color3] = colors;

console.log(color1); // "red"
console.log(color2); // "green"
console.log(color3); // "blue"
```
必要な要素のみを取り出すことも可能です。

```js
// 最初の2つを取り出し、3番目は無視
const colors = ["red", "green", "blue"];

// 2番目をスキップしたいので、 , で飛ばす
const [first, , third] = colors;

console.log(first); // "red"
console.log(third); // "blue"
```
### デフォルト値を設定する
```js
const colors = ["red"];

// 2番目と3番目の要素はデフォルト値を設定
const [color1, color2 = "green", color3 = "blue"] = colors;

console.log(color1); // "red"
console.log(color2); // "green"（デフォルト値）
console.log(color3); // "blue"（デフォルト値）
```

## ネストされた分割代入

オブジェクトや配列がさらにネストされた場合でも分割代入を使って簡単に取り出すことができます。

### オブジェクトの場合
```js
const person = {
  name: "Tom",
  address: {
    city: "New York",
    zip: "10001"
  }
};

// addressオブジェクトのcityとzipを分割代入
const { name, address: { city, zip } } = person;

console.log(name);  // "Tom"
console.log(city);  // "New York"
console.log(zip);   // "10001"
```
### 配列の場合
```js
const colors = [["red", "green"], ["blue", "yellow"]];

// ネストされた配列を分割代入で取り出す
const [[color1, color2], [color3, color4]] = colors;

console.log(color1); // "red"
console.log(color2); // "green"
console.log(color3); // "blue"
console.log(color4); // "yellow"
```

# まとめ

分割代入は、複雑なデータをスッキリとシンプルに扱える便利な機能です！
ReactやTypeScriptの開発では頻出らしいので、手足のように扱えるよう習得を目指します！
プログラミング練習記録　3日目：C# 基本文法：変数、条件分岐、ループ

### 1.本日の作業内容
　C# 基本文法：変数、条件分岐、ループ 復習

### 2.作業目的
　・基本文法の復習。
 　（ちなみに案件の異動でC#使わなくなりました...）

## 

### 1.変数
#### 変数とは...「値を一時的に保存するための名前付きの記憶領域」のこと。
C#は静的型付け言語なので、変数には必ず型が付く。
　例）```int  sting  bool```　など
→型によって使える演算子や、扱える値の種類が変わる。

###### 変数には大きく分けて以下の2種類がある：
値型（Value Type）：```int, double, bool, struct``` など
　→ 値そのものがスタックに格納され、代入時には値がコピーされる。
参照型（Reference Type）：```string, class, object, array``` など
　→ ヒープ上に格納され、変数はその参照（アドレス）を保持する。

###### 型推論
C#では var を使うことで型推論によって自動的に型が決まる。
型はコンパイル時に決定されており、動的ではない。

サンプル
```
int age = 20;
string name = "佐藤";
bool isStudent = false;
var job = "police";
var fathersAge = 45;

Console.WriteLine(age);
Console.WriteLine(name);
Console.WriteLine(isStudent);
Console.WriteLine(job);
Console.WriteLine(fathersAge);
```

出力結果
```
20
佐藤
False
police
45
```

##
### 2.条件分岐（if / else）
#### 特定の条件に応じて異なる処理を実行するための制御構文
基本形は下記の通り。
- if (条件)：条件が true のときのみ実行される
- else：if の条件が false のときに実行される
- else if：複数の条件を順に評価する場合に使う

サンプル
```
int age = 20;
string name = "佐藤";
bool isStudent = false;
var job = "police";
var fathersAge = 45;

// if(条件式)
if (age == 20 && isStudent)
{
    Console.WriteLine(name);
    Console.WriteLine(age);
} 
// 条件が当てはまらないとき
else
{
    Console.WriteLine(job);
    Console.WriteLine(fathersAge);
}
```

出力結果
```
police
45
```

##
### 3. 繰り返し（ループ）
#### ある処理を繰り返し実行するための制御構文
代表的なループは下記の通り
- for 文：回数が決まっている場合に使う
- while 文：条件が true の間、繰り返す
- foreach 文：コレクション（配列・リストなど）を順番に処理する

for文サンプル
```
for (int i = 1; i <= 3; i++ ){
    Console.WriteLine(i);
}

// 出力
1
2
3
```

while文サンプル
```
int age = 20;
while (age < 25)
{
    age++;
    Console.WriteLine(age);
}

// 出力
21
22
23
24
25
```

foreach文サンプル
```
string[] foods = { "寿司", "天ぷら", "そば" };
foreach(string food in foods)
{
    Console.WriteLine(food);
}

// 出力
寿司
天ぷら
そば
```

## まとめ
なんとなく使わずに、ちゃんと意味と使い分けを意識したいですね。
Nuxt3のルーティングについて

# はじめに
`Nuxt3`で開発する際に、ページのルーティングについて下記のように戸惑うことがあります。
たとえば、「`app.vue`には何を書いたらいいの？？」。
Next.jsのように自由に書いているとルーティングに失敗してしまいます。
この記事では、私を含めてルーティングについての備忘録を残しておきます。

# ディレクトリ構成
`Nuxt3`では、ルーティングする際は`components`や`pages`フォルダを別に作成してその配下にVueファイルを配置するようにします。

ちなみに`app.vue`は、プロジェクト作成時の時と同じ階層になります。

```
.
└── Project/
    ├── .nuxt
    ├── .output
    ├── components/
    │   └── navbar/
    │       └── navbar.vue
    ├── node_modules
    ├── pages/
    │   ├── adminUsers
    │   ├── generalUsers/
    │   │   └── registration/
    │   │       └── registration.vue
    │   ├── index.vue
    │   ├── public/
    │   │   ├── favicon.ico
    │   │   └── robots.txt
    │   └── server/
    │       └── tsconfig.json
    ├── app.vue
    ├── nuxtconfig.ts/
    │   ├── package.json
    │   └── package-lock.json
    ├── README
    └── tsconfig.json
```

# pagesフォルダにアクセスするには`app.vue`は記載する内容
前述した`pages`フォルダにトップページ`app.vue`からアクセスするには、`<NuxtPage />`コンポーネントが必要になります。

https://nuxt.com/docs/api/components/nuxt-page

```app.vue
<template>
  <div>
    <NuxtPage />
  </div>
</template>
```

# `index.vue`を作成して共通コンポーネントを読み込む
`index.vue`を作成して共通のコンポーネントを作成します。この`index.vue`があることでプロジェクトを起動して最初のページが表示された時にレイアウトが表示されるようになります。

```pages/index.vue
<script setup="ts">
import { Navbar } from "#components";
</script>

<template>
    <Navbar/>
    <div>
        
    </div>
</template>
```
`Navbar`コンポーネントは、`components`ディレクトリで作成後に、`index.vue`にインポートしています。
べつの話になりますが、ページ遷移するときに使用するモジュール`useRouter`は、管理パッケージで<b>インポートしなくても</b>使えます。

この点は、`Next.js`とは異なる点です。
```components/navbar/nabvar.vue
<script setup="ts">
const router = useRouter();
const clickRegistration = ()=>{
    router.push('/generalUsers/registration/registration');
}
</script>
<template>
    <v-card>
        <v-layout>
            <v-app-bar color="primary">
                <v-app-bar-nav-icon variant="text" @click.stop="drawer = !drawer"></v-app-bar-nav-icon>
                <v-toolbar-title>My Todo Task</v-toolbar-title>
                <template v-if="$vuetify.display.mdAndUp">
                    <v-btn icon="mdi-magnify" variant="text"></v-btn>
                    <v-btn icon="mdi-filter" variant="text"></v-btn>
                </template>
                <v-btn @click="clickRegistration">Register</v-btn>
            </v-app-bar>
        </v-layout>
    </v-card>
</template>
```

# ルーティングの確認
では、`app.vue`に`<NuxtPage />`コンポーネントを追加したことでページ遷移できるか確認してみましょう。
ナビゲーションバーの、「Regiter」ボタンをクリックすると...

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1169664/349b0ab0-e4a9-4b45-9dae-332b56d452bb.png)

ちゃんと登録ページに遷移できましたね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1169664/c70cad88-96bd-471f-ae60-78aa668c0bc1.png)


以上です。

# 参考サイト

https://nuxt.com/docs/api/components/nuxt-page

https://nuxt.com/docs/guide/directory-structure/components

https://qiita.com/Cut/items/8acbdd0e2b6687b3cb9f

https://regex101.com/
【放棄】Data Protection Superbadge Unit　はっきり言って時間の無駄です。しない方がいい



https://trailhead.salesforce.com/content/learn/superbadges/superbadge_data_protection_sbu

+ データ破損イベントの影響を受けたレコードを識別します。
+ レコードデータを以前の値から復元します。
+ 組織データをバックアップするために毎月のエクスポートを設定します。
+ 将来のデータ損失を防ぐためにユーザー アクセスを調整します。


# データ漏洩クイズ

データ漏洩に関する質問に答えます。

思ったのとかなり違いましたね.... 


# データ損失の特定とデータの復元

データ破損イベントの影響を受けたすべてのレコードを識別し、正しいデータを復元します。


:::note alert
We can't find all of the expected emails were restored. Make sure you've identified all contacts affected by the data corruption event.


復元されたはずのメールがすべて見つかりません。データ破損イベントの影響を受けたすべての連絡先を特定していることを確認してください。
:::

何がしたいか全く分からん。


:::note alert
We can't find all of the expected emails were restored. Make sure you've identified all contacts affected by the data corruption event.


復元されたはずのメールがすべて見つかりません。データ破損イベントの影響を受けたすべての連絡先を特定していることを確認してください。
:::

解説らしくものがあるけど、読んだら余計に意味が分かりません。何を言っているのかさっぱり分からん。

https://www.capstorm.com/blog/data-protection-superbadge-insights/

履歴のレポートを見ても私が変更したレコードしかない。どんな意味がある？当然だろう私が更新したんだから

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/1083c85b-536c-487f-aff4-28a0acf25ee8.png)

このコメントを見ても何がしたいかさっぱり分かりませんね。

https://www.youtube.com/watch?v=GuXc4WR5_6s

これって、本当に機能している？項目の更新履歴は私が触った分しかないので、判断できませんね。

You have to replace Contact email Id with Givene Email Id
連絡先のメールIDを指定されたメールIDに置き換える必要があります

どこかに正しいメールのListがある？


SELECT contactId, Field FROM contactHistory で検索したけど何もない


書かれていたユーザリストでメールアドレスを修正しましたがエラーのまま。ダメだ。

+ [何が悪いんだろうか？](https://qiita.com/Keiji_otsubo/items/f1d47ae9ad7a064f6c57)

ログを見てみ分からん

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/f816dbfd-5850-45ef-aae9-b26dd0250366.png)


# データ損失の防止と保護

組織データをバックアップし、それに応じてアクセス レベルを調整することで、予防的なセキュリティ対策を講じます。

:::note alert
We can't find the expected scheduled job that indicates a monthly data backup.
:::



# データ保存クイズ

組織の Salesforce データの保存に関する質問に答えます。



# 新しい環境でも更新履歴はないな。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/e1df7ebf-589d-40dd-a52f-4c8fd9d4f955.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/3bc50338-a660-4144-adf3-a0a863a4ff2c.png)


https://github.com/TechNewbieGT500/DATA-PROTECTION-SUPERBADGE-UNIT/tree/main
100. Same Tree

# 問題内容
入力された二分木がすべてのノードについて同じ数字を持っているか調べ同じ構造の二分木か判別する関数を作る。

# 解答例
```python:sample
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def isSameTree(self, p: Optional[TreeNode], q: Optional[TreeNode]) -> bool:
        if not p and not q:
            return True
        if not p or not q:
            return False
        return p.val == q.val and self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right)
```

# ポイント
* 両方のrootノードについて、どちらもNullなら同じ二分木、片方だけNullなら異なる二分木という処理を書き忘れないように注意
* 再帰呼び出しを使うことで、rootとleftに分岐する部分、そしてrightに分岐する部分が全て一致するかを簡潔に判別できる
【SQL】デッドロック

# はじめに

こんにちは。アメリカに住みながら、独学でエンジニアを目指しているTairaです。
今回は、トランザクションを勉強した際に必ず出てくるデッドロックについて、記事にしていこうと思います。

---

## デッドロックとは？

**デッドロック（Deadlock）** とは、複数のトランザクションがお互いに**相手のロック解除を待っている状態**になり、**永久に処理が進まなくなる**ことを指します。

---

## 例えばで理解

以下の2つのトランザクションが同時に動いている状況を想像してみましょう。

### ● トランザクションA
1. `users` テーブルのレコードをロック
2. 続いて `orders` テーブルを更新しようとして待機

### ● トランザクションB
1. `orders` テーブルをロック
2. 続いて `users` テーブルを更新しようとして待機

このとき、
- AはBが持っている`orders`のロックを待っている
- BはAが持っている`users`のロックを待っている

→ **お互いに待ち続けるため、永久に進まない状態 = デッドロック**

---


## なぜ問題か

- デッドロックが起きると **トランザクションが終了しない** 
- その他の処理も待たされるため、**システム全体のパフォーマンスが低下**
- 最悪の場合、システム停止やエラーの原因に

---

## 対策方法

| 方法 | 内容 |
|--------|------|
| **ロック順序を統一** | すべてのトランザクションで **同じ順番でテーブルをロック**することで、循環待機を防げる |
| **タイムアウトの設定** | 一定時間ロックが取れなければ、自動でトランザクションを中断 |
| **短時間でトランザクションを終える** | 処理を短くすることでロック保持時間を減らす |
---

## SQLでの例 (MySQL)

```sql
-- トランザクションA
START TRANSACTION;
UPDATE users SET name = 'Alice' WHERE id = 1;

-- Bがordersを先にロックしていると、Aはここで待機
UPDATE orders SET status = 'done' WHERE user_id = 1;
```

```sql
-- トランザクションB
START TRANSACTION;
UPDATE orders SET status = 'done' WHERE user_id = 1;

-- Aがusersをロックしていると、Bはここで待機
UPDATE users SET name = 'Bob' WHERE id = 1;
```

---

## まとめ

| 項目 | 内容 |
|------|------|
| 定義 | お互いのロックを待ち合って進めない状態 |
| 原因 | ロック取得順序のバラバラ、長いトランザクションなど |
| 対策 | ロック順序の統一、タイムアウト設定、再試行処理など |
TypeScript:6.appendChild

# DOM操作をするときの基本appendChild
### 例
```ruby:qiita.rb
private updateSelectedList(): void{
    const selectedItems = this.foodItems.filter(item => item.selected);
    const ul = document .querySelector('.selected-foods') as HTMLUListElement;

    ul.innerHTML = ''; 

    selectedItems.forEach(item => {
        const nameEl = item.element.querySelector('.food__name') as HTMLDivElement;
        const li document.createElement('li');
        li.textContent = nameEl.textContent;
        ul.appendChild(li);
    });
}
```
上記のコードは選択された食べ物が<ul class="selected-foods"> に1個ずつ表示される

### 詳しく解説
⓪const nameEl = item.element.querySelector('.food__name') as HTMLDivElement;
item要素にある`foodname`クラスを取得して格納する

①const li = document.createElement('li');
HTMLの`<li>`要素をJavaScriptで作ってる

②li.textContent = nameEl.textContent;
`<li>`要素のtextContentに'foodname'クラスのtextContentを代入

③ul.appendChild(li);
作った`<li>`を`<ul>`に追加している

## アイテムネームを文字列結合してそれをulのtextContentに代入すればいいとおもっていたけどやっぱり一個ずつli要素を作ってappendChildするやり方がいいの？

**回答**
質問の「文字列結合でtextContentに代入」も動くは動く、、、
「リストとしての見た目・柔軟性・保守性」を考えると、`<li>`を１つずつ作ってappedChildする方がおすすめ

**textContentに文字列を結合して代入した場合**
・ulタグの意味がなくなる
・自動的に改行されない
・CSSで１つずつスタイリングできない
・削除や追加など、個別操作ができない

**1つずつliを作ってappendChildした場合**
・HTMLとして正しい構造
・見た目がリストして整う
・CSSでリスト項目ごとに装飾が可能
・削除やクリックイベントをli単位で制御可能
・拡張しやすい

**実務やアプリ開発では**
・項目の右側に「削除」ボタンをつける
・アイテムにクラスをつけて色を変える
・順番を入れ替える
このような機能はtextContent方式では実現が難しく１つずつ要素を作る胞子が圧倒的に強い。
#0110（2025/04/19）クライアント・サーバ間の通信プロトコルと技術

# クライアント・サーバ間の通信プロトコルと技術

クライアント・サーバ間でデータや処理をやり取りするための通信プロトコルや技術は、システム設計や開発において非常に重要な役割を果たしています。この記事では代表的な通信プロトコルや技術をカテゴリごとに分類し、それぞれの特徴を詳しく解説します。

## 1. REST API

REST（Representational State Transfer）は、HTTPプロトコルを利用し、ステートレスな通信を行うAPI設計スタイルです。

- **特徴:**
  - エンドポイントをリソース単位で設計
  - HTTPメソッド（GET, POST, PUT, DELETEなど）で操作を明示
  - JSON形式でデータをやり取りするのが一般的

- **メリット:**
  - シンプルで分かりやすい
  - ブラウザやモバイルアプリから簡単に利用可能
  - 広く普及しているため、ツールやサポートが豊富

- **デメリット:**
  - 柔軟性が低く、必要以上のデータを取得することがある
  - APIが増えると管理が複雑になる場合がある

## 2. gRPC

Googleが開発した、HTTP/2をベースにしたRPC（Remote Procedure Call）フレームワークです。

- **特徴:**
  - Protocol Buffers（protobuf）を使用したバイナリ形式
  - 明確な型定義が可能（.protoファイル）
  - 双方向ストリーミング通信が可能

- **メリット:**
  - 高速で軽量、低レイテンシ
  - 型安全性が高く、バージョン管理しやすい
  - 複数の言語に自動生成の仕組みが整備されている

- **デメリット:**
  - バイナリ形式であるためデバッグがやや難しい
  - ブラウザ直接アクセスには向いていない

## 3. GraphQL

Facebookが開発した、クエリ言語を利用したAPIです。

- **特徴:**
  - クライアント側で必要なデータのみをリクエストできる
  - 明確なスキーマ（型定義）を定義する
  - クエリ、ミューテーション、サブスクリプションという3つの操作がある

- **メリット:**
  - クライアント側で柔軟にデータを取得可能
  - API呼び出し回数を減らしパフォーマンス向上

- **デメリット:**
  - クエリの自由度が高いためサーバ側での負荷コントロールが必要
  - クエリ最適化などサーバ側の複雑性が増す

## 4. SOAP

SOAP（Simple Object Access Protocol）はXMLをベースにした通信プロトコルです。

- **特徴:**
  - XMLを用いた通信
  - WSDL(Web Services Description Language)でサービス記述

- **メリット:**
  - 高い標準化とセキュリティ機能
  - エンタープライズ環境で広く使われる

- **デメリット:**
  - XMLのため通信量が多くパフォーマンスが低い
  - 設定や管理が複雑

## 5. JSON-RPC/XML-RPC

RPC（Remote Procedure Call）をJSONまたはXML形式で簡単に実現したものです。

- **特徴:**
  - シンプルなリクエストとレスポンス形式
  - HTTPやWebSocket上で使える

- **メリット:**
  - 単純で軽量なため、実装が容易

- **デメリット:**
  - 型やインターフェースの明確な管理が難しい

## 6. WebSocket

HTTP接続を常時オープンし、双方向リアルタイム通信を可能にする技術です。

- **特徴:**
  - 双方向リアルタイム通信
  - ゲームやチャットアプリなどでよく使用

- **メリット:**
  - 高速でリアルタイム性が高い

- **デメリット:**
  - 常時接続のためサーバリソース管理が重要

## 7. MQTT

IoTなどの低帯域幅環境向けの軽量なメッセージングプロトコルです。

- **特徴:**
  - 軽量で低電力消費
  - Publish/Subscribeモデル

- **メリット:**
  - IoTデバイスやセンサーデータに最適

- **デメリット:**
  - 大規模データ転送には不向き

## ユースケース別の選定例

| ユースケース | 適したプロトコル・技術 |
|-------------|-------------------|
| 通常のWebサービスAPI | REST |
| マイクロサービス間の通信 | gRPC |
| 柔軟なデータ取得を重視するフロントエンドAPI | GraphQL |
| 金融・医療など高セキュリティ | SOAP |
| リアルタイム性重視 | WebSocket, gRPC |
| IoTやセンサーデバイス | MQTT |

## まとめ

システムの目的や要件に応じて、適切なプロトコルや技術を選定することが重要です。近年では、異なる技術を組み合わせて利用することも多く、各技術の特性を理解し、適切に設計することが求められます。
#0109（2025/04/19）メタ構文変数

# メタ構文変数

**メタ構文変数**（etasyntactic variable）とは、プログラミングやコンピュータサイエンスの文脈で、コードの説明やサンプルを示すときに、具体的な名前が重要ではない変数や関数、オブジェクトなどを一時的に表現するために使われる汎用的な名前のことです。

## メタ構文変数の由来

- 	「foo」「bar」の起源は明確には分かっていませんが、一般には第二次世界大戦時の米軍に由来するとされています。
- 	軍隊用語の俗語（FUBAR：「Fouled Up Beyond All Recognition」、直訳すると「めちゃくちゃに壊れている」）から来ているという説が有力です。

## メタ構文変数一覧

| No. | メタ構文変数 | 読み（カタカナ） | 
|-----|--------------|------------------|
| 1   | foo          | フー             | 
| 2   | bar          | バー             | 
| 3   | baz          | バズ             | 
| 4   | qux          | クックス         |
| 5   | quux         | クークス         | 
| 6   | corge        | コージ           | 
| 7   | grault       | グロールト       |
| 8   | garply       | ガープリー       | 
| 9   | waldo        | ウォルド         | 
| 10  | fred         | フレッド         | 
| 11  | plugh        | プラフ           |
| 12  | xyzzy        | ジズィー         | 
| 13  | thud         | サッド           |
AI駆動でTODOアプリを作ってみました

# はじめに
* 暫くの間、開発をしていなかったためリハビリもかねて開発してみました
* シンプルなTODOアプリを開発
    * (CursorとGPT使ってAI駆動で開発していたんだけど進化しすぎ...）

# システムについて
* フォームに入力してタスクを追加できる
* 削除もできる
* チェックを入れると取り消し線が入る
![スクリーンショット 2025-03-06 171916.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4014626/f505aa8e-d647-48df-a8b3-3173041afea6.png)

# 技術スタック

## インフラ

* EC2 + Docker + GitHubActions
    * 手動ではなく、自動ビルドのパイプライン構築を体験したかった
    * 実務に繋がる「CI/CD」の最初の一歩として導入
    * プッシュすると自動でDockerイメージがビルドされる設計

* リバースプロキシはNginxを使用
    * Apacheでもよかったが、EC2の無料枠内で作りたかったのでメモリ使用量が少なくCPU効率も良いと言われてるNginxを採用

## 使用言語と選定理由
* React（TS)
    * 状態管理やイベントハンドリングが直感的
    * 近年のトレンドNext.jsへのステップにもなるため
* SpringBoot
    * 今後、エンタープライズシステムに関わってみたいなーって思いで選択
    * TSでなんちゃってバックエンドを書くことが多かったので業務で使われることが多い言語を触ってみたかった

# アーキテクチャ
* RESTfulな設計
    * 操作に応じてHTTPメソッドを使い分けるシンプルな設計
    * 標準的なステータスコードを使用
    
* （時間があるときにシーケンスやアーキテクチャの図面を作ります）

# 苦労したこと・工夫したこと

## その1.ファイルの分離で悩んだ

### パターン1. SOLID原則に従うように分ける
* TODOの各操作単位(追加処理、削除処理、状態管理）で切り分ける
    * SOLID原則のS部分（単一責任の原則）に従うよう各処理ごとにファイルを分離する
    * 関心の分離を行うことで既存のコードを変更せずに追加しやすくなる。
        * O（開放/閉鎖原則 / Open-Closed Principle）も従うようになる
    
### パターン2. Reactのカスタムフックを使用する
* 各ハンドラで切り分けるというより一連の操作を一つのファイルに集約させて処理を担わせる（まるでインスタンスが存在しないようなクラスみたいな）

* 正直どっちでもよかったんだけどReactの独自機能であるカスタムフックを使用してみたかったのでパターン2を採用（ただApp.tsx部分のライブラリ部分がなんか汚くなってしまった...ハンドラの方がきれいだったかもしれないとも思いつつ）
    
## その2.スワップ領域を増やした

### 領域を増やした経緯
* 当初、EC2内にもDockerを入れてコンテナ運用で開発しようかと思ったのだが処理がめちゃくちゃ重かったので断念（インスタンスが処理落ちで固まってしまう）
→
* ECS/fargateで運用してみるか！
→
* 思ったより学習コストが高く、まずはEC2で簡単に運用することに変更
→
* しかし、再び問題発生。MySQLをインストールするとインスタンスがメモリ容量不足により落ちてしまう
→
* GPTに相談したところ、スワップ領域を増やせばできるかもと提案される（あーたしかに、外部記憶余ってるしSSDだからいいかなーみたいな雑な考えでスワップ領域を増やすか―と思って増やす。）
* ついでに監視ツールとしてHTOPもインストール
→
* ひとつのインスタンスで動かすことに成功する

### その3.Javaの学習

* Javaは厳しすぎる！:confounded:
    * ここで言及することもないけどね。
    * クリーンパッケージでビルドしてテストして～みたいな一連の流れはつかめた感

### その4.CORSエラーやNginxの設定で少し詰まった
* 単なる権限不足や構文の理解不足といった些細なことだったけどおかげさまでCORSやNginxについてほーーーんと少しだけ理解できた。


# 改善点
* セキュリティ対策をしっかりと
* エラーハンドリングを設ける

# 今後の展望
* ECS/Fargateを使用して本格的にクラウドでもコンテナ運用できるようにしたい
* 認証機能を設ける
* Next.jsを使用して開発してみる

# さいごに
* GPT、Cursor凄すぎる
    * 対話して開発できるから楽しい

# ソースコード
https://github.com/uetyama/TODOAPP-rest