OmniAICreator/Qiita-1.07M huggingface dataset:
【ChatGPT】に何かをサボるためのポイントを教えてもらうためのPromptです。


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

　今回は、ChatGPTに何かをサボるためのポイントを教えてもらうためのPromptです。

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

　OpenAIから
　　Operatorについての
　　　ポストがありました。
　　　　[OpenAI公式ポスト](https://x.com/OpenAI/status/1892832374997631250?t=Wl8Z3OjmWc8jMuLzLSGIcQ&s=19)

>（ChatGPT翻訳）
>Operatorは現在、オーストラリア、ブラジル、カナダ、インド、日本、シンガポール、韓国、イギリス、そしてChatGPTが利用可能なほとんどの地域のProユーザー向けに展開中です。
>
>EU、スイス、ノルウェー、リヒテンシュタイン、アイスランドでの提供については引き続き対応中です。最新情報をお知らせします！

　はい、日本での利用も
　　可能になります。
　　　……あっ、ロールアウト完了した！
　　　　[OpenAI公式ポスト](https://x.com/OpenAI/status/1892851393775476985?t=2eWzedWFjrbWZG8GbE2QmA&s=19)

　ちなみに
　　OpenAIのOperatorとは
　　　2025年1月23日に発表された
　　　　AIエージェント。

　　OpenAI独自Webブラウザを
　　　直接操作してタスクを
　　　　自動化するツールです。

　　詳しくはこちら。
　　　[Operatorの紹介](https://openai.com/index/introducing-operator/)

　なお、
　　使えるのは、
　　　まだChatGPT Proユーザーのみ。
***
　次に

　OpenAIが
　　悪意ある使用を阻止するための
　　　取り組みをアップデートしました｡
　　　　[Disrupting malicious uses of AI](https://openai.com/global-affairs/disrupting-malicious-uses-of-ai/)
***
　次に

　リコーの管理職「2軍制度」。
　　スキルが習得できれば1軍へ、
　　　できなければさらに降格。

　[日本経済新聞 電子版ポスト](https://x.com/nikkei/status/1892567670312055184?t=zGP9I-nuXtfUnNZsmdfPeQ&s=19)

　[日本経済新聞](https://www.nikkei.com/article/DGXZQOUC288QD0Y5A120C2000000/?n_cid=SNSTW005)

　記事の内容は
　　読んでないけど（ログインが必要）
　　　ここには、生成AIも
　　　　含まれるんだろうなぁ……。
　　　　　頑張れ！
***
　では、【本題】です。

　今回は、
　　ChatGPTに
　　　何かをサボるためのポイントを
　　　　教えてもらいましょう。

　“サボるなんて、とんでもない”と
　　言わずに、Promptを使ってみて。
　　　休憩中の遊びだと思って。

　このPromptを使うと
　　いかに仕事をサボるかの
　　　助言がもらえます。

　こちらがPromptです。
　　＊＊＊にサボりたいことを
　　　入力して送信してください。
```Text:限界まで”サボるためのポイントPrompt
ChatGPTで「＊＊＊」を“限界まで”サボるためのポイントを教えてください。
```

　入力を具体的にすると、
　　助言も具体的になります。

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

　今回は、ここまで。
【OCI】Terraformでインスタンスを作成する際にCloud-initを設定する【リソースマネージャ】

# cloud-initとは？

インスタンスの初期設定を自動化するツールです。

インスタンス起動時に、パッケージのインストールやユーザー作成、設定ファイルの変更などを自動で実行できます。AWSやOCIなど主要なクラウドサービスでサポートされています。

# metadataブロックでスクリプトファイルを指定

TerraformでOCIのインスタンスを作成する場合、user_dataとしてbase64でエンコードしたファイルを指定することでcloud-initを利用できます。

```hcl:main:tf
resource "oci_core_instance" "this" {
  count               = var.env == "develop" ? 1 : 2
  availability_domain = var.availability_domain
  compartment_id      = var.compartment_id_sub
  display_name        = "${var.name}-${count.index}"
  shape               = var.shape

  shape_config {
    ocpus         = var.ocpu
    memory_in_gbs = var.memory
  }
  source_details {
    source_id   = var.source_id
    source_type = var.source_type
  }
  create_vnic_details {
    nsg_ids = [
      var.security_group
    ]
    subnet_id = var.subnet_id
  }
  metadata = {
    ssh_authorized_keys = var.ssh_keys
    user_data           = base64encode(file("${path.module}/userdata/setStartup.sh"))
  }
}
```

# スクリプトファイルのサンプル

Nginxをインストールして起動する場合のサンプルです。

```bash:setStartup.sh
#!/bin/bash
dnf update -y

dnf install emacs -y
dnf install nginx -y

systemctl enable nginx
systemctl start nginx

firewall-offline-cmd --permanent --add-port=80/tcp
firewall-cmd --reload
```
Flutterでボタン幅を画面いっぱいにする方法

# Flutterでボタン幅を画面いっぱいにする方法

## **はじめに**

FlutterでUIを調整する際、ボタンの幅を画面いっぱいにしたいことがあります。しかし、単に`width: double.infinity`を指定するだけでは、親ウィジェットの影響で意図した通りにならないことも。

この記事では、**「なぜボタンの幅が意図した通りにならないのか？」** という疑問を解決しながら、3つの具体的な方法を解説していきます。

---

## **ボタン幅を画面いっぱいにする方法**

Flutterでボタンを最大幅にする方法はいくつかあります。それぞれの特徴と使いどころを見ていきましょう。

### **方法1: `SizedBox` を使う（単独のボタン向け）**

最も簡単な方法は `SizedBox` を使うことです。

```dart
SizedBox(
  width: double.infinity,
  child: ElevatedButton(
    onPressed: () {},
    child: Text("ファイルを選択"),
  ),
)
```

✅ **ポイント:**
- `SizedBox(width: double.infinity)` によって **ボタンの幅を強制的に最大化** します。
- **単体で置くボタン** に適した方法です。

🚨 **注意点:**
- `Row` や `Column` の中にあると、意図したサイズにならないことがあります。

---

### **方法2: `Expanded` を使う（`Row`や`Column`の中で使う場合）**

`Row` や `Column` の中でボタンを最大幅にしたい場合は、`Expanded` を使用します。

```dart
Row(
  children: [
    Expanded(
      child: ElevatedButton(
        onPressed: () {},
        child: Text("ファイルを選択"),
      ),
    ),
  ],
)
```

✅ **ポイント:**
- `Expanded` を使うことで、**親ウィジェット（RowやColumn）の幅いっぱいにボタンを広げる** ことができます。
- **`Row`や`Column` の中にボタンを配置する場合に適している** ので、フォームのボタンなどでよく使われます。

🚨 **注意点:**
- `Expanded` を使う場合、必ず **`Row` または `Column` の中** に配置する必要があります。

---

### **方法3: `Flexible` を使う（`Expanded` より自由度が欲しい場合）**

`Flexible` は `Expanded` と似ていますが、**他の要素とのバランスを考慮しながらサイズ調整をしたい場合** に向いています。

```dart
Row(
  children: [
    Flexible(
      child: ElevatedButton(
        onPressed: () {},
        child: Text("ファイルを選択"),
      ),
    ),
  ],
)
```

✅ **ポイント:**
- `Expanded` と異なり、**ボタンのサイズを必要に応じて調整できる** ので、レイアウトの自由度が高い。
- 他の要素と **バランスをとりながら幅を調整する** 場合に便利。

🚨 **注意点:**
- `Flexible` は **他の要素とのバランスに依存するため、場合によっては意図しないサイズになることがある** ので、適用範囲を考慮する必要があります。

---

## **まとめ: どの方法を選べばいい？**

ボタンを画面いっぱいに広げたい場合、状況に応じて適切な方法を選びましょう。

✅ **単独のボタンなら `SizedBox(width: double.infinity)`**
✅ **`Row` や `Column` の中なら `Expanded`**
✅ **柔軟なレイアウト調整をしたいなら `Flexible`**

🚀 **おすすめの学習ポイント:**
- `Row` と `Column` の違いを理解する。
- `Expanded` と `Flexible` の違いを試しながら学ぶ。

適切なレイアウトを選んで、快適なUIを作っていきましょう！
blenderのスムーズ、ベベル、投影の切り替え方法、自動スムーズ

# ベベルモディファイアで丸くするとき
オブジェクトモードに変更してから使用する

# スムーズシェイド
オブジェクトモードで使用出来る

# 入門書には テンキー5 しか載っていなかったのでメモ

投影は `透視投影` と `平行投影` の２つのモードで切り替えます。

通常は `テンキー5` で切り替えるようですがもしGUIから切り替える場合は下の画像のようにすればいいようです

#### [ビュー] → [透視投影/平行投影 テンキー5]
![透視投影と並行投影.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3957418/00ffa182-4d91-48eb-aeab-ed51675b3eb0.png)


# 自動スムーズが4.1では無くなっている

https://k06.hatenablog.com/entry/2024/03/31/145842
【Rails 8】Bootstrapのインストール

# 開発環境
Rails 8.0.1
Ruby 3.2.2
Bootstrap 5.3.3

Rails 7の場合はこちらの記事から　
[【Rails 7】Bootstrapのインストール](https://qiita.com/arata0520/items/4330c2be8740bc560390)

# 導入手順
## 1.Gem導入
Gemgileに以下２つのgemを追加
```:Gemfile
gem "dartsass-rails"
gem "bootstrap", "~> 5.3.3"
```
ターミナルにて、インストール
```:terminal
bundle install
```
## 2.dartsassのインストール
ターミナルにて以下のコマンドを実行
```:terminal
rails dartsass:install
```
## 3.CSS編集
application.scssに以下のコードを追加。（application.cssファイルは不要なため削除。）
```css:application.scss
@import "bootstrap";
```

## 4.javascriptの設定
a) config\importmap.rb
以下のコードを追記(位置はどこでも良い）
```ruby:config/importmap.rb
pin "bootstrap", to: "bootstrap.min.js", preload: true
pin "@popperjs/core", to: "popper.js", preload: true
```
b) app/javascript/application.jsに以下のコードを追記
```ruby:application.js
import "@hotwired/turbo-rails"

import "@popperjs/core"
import "bootstrap"

import "controllers"
```

## 4.デプロイ時
### a) 開発環境でscssが反映されるようにする
#### Procfile.devの書き換え
①：「Procfile.dev」のファイル名を「Procfile」に変更
②：中身の修正(bin/を削除）

```diff_ruby:Procfile
- web: bin/rails server -p 3000
+ web: rails server -p 3000

- css: bin/rails dartsass:watch
+ css: rails dartsass:watch
```
rails sの代わりに以下のコマンドで実行(foremanを使って実行）
```diff_terminal:terminal
foreman start -f Procfile
or
foreman start
```

### b) 毎回実行する場合
```terminal:terminal
rails dartsass:watch
rails server
```
# 参考

https://medium.com/@xnjiang/how-to-use-bootstrap-in-rails8-cd0d53f1c3bc
Open Source Conference 2025 Tokyo/Spring AIの進化で変わる開発手法 ─ AIのトレンドとAI駆動開発の始め方、これから必要となるノウハウを解説

:::note warn
この記事は現地からの速報でした。
漏れ抜けに気づいたので、帰ったら追記します。
:::

## 本日のセミナーイベント
https://event.ospn.jp/osc2025-spring/

## AIがとりまく開発現場の変化
「技術ナレッジ共有の場」
AIの進化でで大きく変わりつつある
開発だけでなく、ビジネス目線でも違う

Builder Lab(AIエージェントの開発セミナー)の様子。サム・アルトマン氏との撮影で

- 営業
- マーケター
- 経営者
- 開発者

がいるし、なんなら開発者より早く作ってる人もいるぐらい
↑AIを使うエンジニアではなく、AIを活用できるエンジニアの価値が高くなっている

## トレンドの変化を追う
ここ2~3週間だけでも多い（が、界隈的には比較的穏やかな方らしい。他業界から見ると凄まじい量）

- AGI化：頭が良くなる
- 活動領域の拡張
  - AIエージェントを介してXR
- 社会実装
- オープンソース化

### AGI化
o1でもIQ133、o3になると更に頭が良くなっていくか
↑ベンチマークの仕方も検討する必要がある？

### 活動領域
テキストからマルチモーダルへ、物理空間だけでなく、XRも

- Muse
- Figure AI
- （なんかいっぱい）

### AIエージェント
人がやること：AIに依頼することを考える
AIがやること：その後の作業全部。目標達成までやる

↑ずっと疑問だが、人間の依頼自体が間違っていたり、人間とAIが見据えている目標の違いのすり合わせはどうするんだろう？
トライアンドエラーをやるなら、今の生成AIのプロンプトエンジニアリングと同じことを、形を変えてやるんじゃないのか？

### 社会実装：導入されない理由をなくしていく
Google AI StudioとChatGPT、j-Moshi（録画）の音声デモ。PCカメラやスマホカメラを使ってインタラクティブな会話ができる
j-Moshiは相槌打ってくれるのいいね！

### オープンソース化
- 基盤モデル（オープンウェイト）
  - DeepSeek
- アプリケーション
  - ClineなどAIエージェント

## ニーズ→開発を高速で回せるAI駆動エンジニアの価値が高まる
要件定義〜運用をAIでやる。
PMからエンジニアへの指示をしていたのが、AI駆動エンジニアからAIへ指示するという流れに変わる
ビジネスと開発の距離を近づけることで、コミュニケーションギャップを削減していく

### 余談：Feloの例
ユーザーの要望を翌日にリリースするぐらい早い開発の事例がある

## AI駆動開発スキル
- AI情報収集力
  - 最新情報を追う
- 要件定義・設計
  - ニーズ対応
  - 動くもの＜使えるもの（保守性・拡張性）
- 実践力
  - 使いながら理解する

↑やればやるほど力がつく、というのは変わらないね

1. 全体の流れを知る：ドキュメントAI＝GEAR.indigoを使ったデモ
1. IT知識を学ぶ：生成結果の正しさを評価するため
1. AI情報収集と体得：集めた情報を使ってみる

### エンジニアリング
1. 文字起こし：tl:dv
1. 要件定義・設計：ChatGPT / GEAR.indigo
1. 実装・運用：Cursor / Replit / Cline

設計までのドキュメントが重要
コンテキストが不足しているとAIを思い通りに動かせない

↑日本語は不利。空気を読む文化のよくない点だね

これを解消するための「ドキュメント生成AI」の需要が高まる。

https://gearindigo.app/

（筆者も勉強中のため、解説は譲る）

https://blog.nocodelab.jp/entry/gear-indigo-intro

プラスアルファの要素として「自己のブランド価値」を考える。
自己の資格研鑽・SNSアカウント育成・キャラ付け（セルフIP）を発信するなど

#### Xおすすめアカウント
- 元木さん: 神威
- tomoyukiさん: AI社員
- 熊井さん: AI駆動開発

は押さえておきたい

### エンジニアオワコン説へ
AIを使いこなすエンジニアが仕事を奪う方に回るので、むしろこれからも価値が上がり続けるよ

## 所感
AIニュースやトレンドを追いかけているだけでも
AIに限らず、技術セミナーを聞いていて私は「わかった気になる＝何もわかっていない」という状況になるのがこわくて、学んだ内容を再度インプットする時間を作ることを重要視していた。が、AIトレンドを見ていると、もうそんなことをやっている余裕すらなくなってきている。
どこかのタイミングで「自分にとって必要なAI」と「必要ではなくても、知っておくべき内容」の取捨選択を考えていかなければならない。

## ちょっとだけ宣伝
私もやってるです

        ↓　　↓　　↓

https://linuc.community/

登壇者へSlackで質問・相談できる環境もあります。
CATechDojoに参加してきたので振り返り！！

こんにちは、とくりんです！
ブログ初めて書くので拙い文章でも読んでいただければ幸いです

初めての投稿はCyberAgent様でのCATechDojoの感想になります！
CATechDojodでは学習型インターンとして一週間社員さんにサポートをもらいながらアプリを開発してきました。

## インターンの概要
参加者は、何らかのプログラミング経験が1～3年程度の学生や、大学院に進学予定の4年生が中心でした。Android開発の経験者は少なく、初心者向けの内容に感じました。ただし、モバイルアプリ開発の経験がある人や、ハッカソンに頻繁に参加している強者もいたため、幅広いレベルの人が集まっていました。

そんな中、今回のテーマとして掲げられたのが Gemini API を用いたチャットアプリの作成 でした。最初に聞いたときは、「本当にそんなものが作れるのか？」と不安になったのを覚えています（笑）。

  ### インターンでのゴール 
このインターンでは、アプリ開発を通じて **「1人でアプリを開発し、リリースできるようになること」** をゴールに掲げられています。
以前、軽くアプリ開発をしたことがある自分にとっては、ちょうどよい目標でした。
さらに、個人的な目標として  **「公式ドキュメントを読解できるほどの技術的な知識を身につけ、開発の流れに慣れること」「AIに頼り切らずに自力で開発を進めること」**  を設定しました。


では、自分がインターンに参加したときの状況についてお話しします。

## 参加時のレベル

Kotlinを始めたきっかけは、大学の技術サークルの先輩の影響でした。
プログラミング自体は、中学校の頃に映像で軽く勉強した HTML・CSS・JavaScript 以来ほとんど触れておらず、知識もほとんど覚えていませんでした。

大学では、週一回のもくもく会に参加しながら学習を進めましたが、学習方法や内容に迷うことが多く、試行錯誤の日々でした。そんな中、夏に CyberAgent様のAndroid BootCamp にほぼ知識ゼロの状態で参加しました。
ここでは、一応読書記録アプリを作成しましたが、AI に頼って開発してしまったことが心残りでした。この経験が、 **「AIに頼らずに開発を進める」** という、今回のインターンでの目標につながっています。

その後、大学の授業やバイトに追われる中で、
 **「プログラミングで何か作りたい気持ち」 と 「分からないことに挑戦し、継続することへの抵抗」**  の間で揺れ動き、ほとんど学習が進みませんでした。
ハッカソンにはいくつか参加したものの、思うような成果を出せず、さまざまな悩みを抱えたまま今回のインターンに応募しました。

そんな やる気だけが空回りしている状態 で参加したインターンでしたが、なぜか **「まあ、なんとかなるだろう」**  という自信に満ちていました。
しかし、その自信は 見事に打ち砕かれることになるのですが……。

長くなってしまったのでまた続きにします。読んでいただきありがとうございました！！

↓これはBootCampで開発したアプリです
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4016682/2b68c075-50cf-478f-b1c7-07e3f6a4f858.png">
三段論法設計をやめよう

# ある開発現場にて

### ショッピングサイトの保守をしているAさん

ある日、Aさんは設計書の中にこんな記載を見つけました。
~~~
手数料が0円の場合
即日配送オプションを選択できるようにする。
~~~

Aさん：先輩、なんで手数料が0円だと即日配送オプションが選択できるんですか？
Aさん：即日配送をお願いするなら、むしろ手数料が余分にかかるような気がしますけど。
先輩：え…確かに。なんでだろうね。昔からある仕様みたいだし、よく分からないね

### Aさん、新しい要件の開発を頼まれる

クライアント：有料会員は手数料無料にしてたんだけど、今後は新しくできたプレミアム会員を手数料無料にして、有料会員からは5%だけ手数料をいただくようにしたいんだ。
Aさん：分かりました。手数料無料になる条件を改修しますね。

～リリース後～

クライアント：有料会員の方から問い合わせがあって、即日配送オプションが選べなくなったらしいんだけど、調べてみてくれない？
Aさん：手数料がかかるようになったので、即日配送オプションが選べなくなったのではないでしょうか？
クライアント：え？即日配送オプションは有料会員向けのサービスだよ。手数料とは関係ないはずだ。

その後、Aさんが保守しているショッピングサイトについて以下の事実が明らかになりました
* リリース当初から、無料会員は手数料がかかり、有料会員は手数料無料という仕様だった
* あるタイミングで、有料会員向けに即日配送オプションが導入された
* その機能が「手数料が0円の場合、即日配送オプションが選択できる」と設計されていた

# 三段論法設計とは
以下のような設計を三段論法設計と名付けました。
1. Xの場合、Yの処理を行うという要件がある
2. 既存の仕様で、Xの場合、必ずZになることがわかっている
3. Zの場合、Yの処理を行う、という設計で1.の要件を実現する

上記の例だとそれぞれ以下に該当します
　X＝有料会員である
　Y＝即日配送オプションが選択できる
　Z＝手数料0円である

# 三段論法設計をしてしまう背景

「有料会員の場合、即日配送オプションが選択できる」という設計にすべきだし、普通はそうするだろうと思います。
上述したのは単純な例ですが、実際はもう少し複雑なケースにて三段論法設計が発生してしまう可能性があるのではないかと考えています

* 例1
  * DBに条件Xを直接的に表現する項目が無く、導出が必要であった
  * 条件Xの判定処理が再利用可能な形で部品化されていなかった
  * たまたま条件Xであれば必ずZになるような条件Zが、使いやすい形で用意されていた 
* 例2
  * DBに条件を直接的に表現する項目Xがあったが、新しいエンティティのDB取得処理追加を避けて、既に取得しているエンティティの情報Zだけで済ませたかった
  * 性能要件上の理由など
* 例3
  * 開発チーム内で「X＝Z」という業務仕様が暗黙の了解になっていたり、当時の仕様ではほぼ同義とみなされたりしていた

# 三段論法設計によって起きてしまうこと
### 背景にある業務仕様が見えにくくなる
三段論法設計をしてしまうと、設計の背景にある業務仕様が見えにくくなってしまいます
Aさんは、「手数料が0円だと即日配送オプションが選択できる」という設計から、「即日配送オプションは有料会員限定のサービスである」という業務仕様を読み取れませんでした。

### 前提となる仕様が変わったときに影響を受ける
三段論法設計は
2. 既存の仕様で、Xの場合、必ずZになることがわかっている
が前提である設計です。ここが崩れるとそもそも成り立たなくなります。
Aさんは、有料会員にも手数料をつける改修を行ったことによって、同時に即日配送オプションが選択できないようになってしまいました。
この手のことは、業務仕様を把握していない限り、事前の影響範囲の調査でも発見されにくいものです。

# 直接的な表現をしよう
三段論法設計をやめて、業務仕様を直接表現する設計を心がけましょう。
これにより、設計の意図が明確になり、変更に対して予期せぬ影響も受けにくくなります。
【Git】２つ以上前（過去）のコミットを修正（超要約）

コミットをできる限り綺麗に残したい勢の皆様、本当にお疲れ様です。
長い説明はしません。コマンドと一口メモだけを残します。

---

1. `git rebase -i 6a8a3d8c`（修正対象の１つ前のコミットIDを指定）
2. (rebase選択画面) 修正したいコミットIDへ移動し pick 文字列を edit へ変更し保存
3. `git status` （状況確認：Last command done に対象コミット情報あり確認）
4. 目的のファイルを開き、修正を行う
5. `git status`（状況確認：修正したファイルのみが modified 状態確認）
6. `git add` 修正したファイル
7. `git commit --amend`（コミットメッセージ変更しても、しなくてもOK）
8. `git rebase --continue`（Successfully 表示されるはず）
9. `git push --force-with-lease origin your_branch`

GitHubで確認し終了.
Word2Vecによる単語ベクトルの学習と演算

# Word2Vecの仕組みを具体例で解説

Word2Vecは、単語の意味をベクトル空間で表現する自然言語処理のテクニックです。
大量のテキストデータから単語の使われ方を学習し、単語をベクトル化します。

## 1. Word2Vecで単語の文脈関係を学習する

Word2Vecは、大量のテキストデータから単語の使われ方を学習します。
以下は簡単な例です。

```
training_contexts = [
    "王様は国を治める",
    "女王は国を統治する",
    "男性は父親になる",
    "女性は母親になる"
]
```

## 2. Word2Vecの学習プロセス

Word2Vecは、以下のステップで単語をベクトル化します。

* 各単語について、周辺単語との関係性を学習する
* ニューラルネットワークを用いて単語をベクトル空間に配置する
* 似た文脈で使用される単語は、ベクトル空間上で近い位置に配置される

例えば、「統治する」という行為に関して「王様」と「女王」は似た文脈で使用されます。
そのため、ベクトル空間上で近い位置に配置されます。

## 3. Word2Vecによるベクトル表現

### 3.1. 2次元表現

理解を容易にするため、2次元での表現を見てみましょう。

```
simplified_vectors = {
    "王様": [3, 4],
    "男性": [2, 3],
    "女性": [2, 1],
    "女王": [3, 2]
}
```

### 3.2. 実際のWord2Vecでの表現

実際のWord2Vecでは、より高次元のベクトルを使用します。

# 10次元ベクトルの例
```
real_vector_example = {
    "王様": [0.2, -0.5, 0.8, 0.1, -0.3, 0.7, 0.4, -0.2, 0.6, -0.4]
}
```
これらの値は自動的に生成され、各次元が具体的に何を表すかは解釈できません。

## 4. Word2Vecのベクトル演算

Word2Vecの興味深い特徴は、ベクトル演算が意味的な関係を反映することです。
有名な例として「王様 - 男性 + 女性 = 女王」があります。

# アナロジー演算の例
```
def analogy_calculation(king, man, woman):
    result = [
        king[0] - man[0] + woman[0],  # x座標
        king[1] - man[1] + woman[1]   # y座標
    ]
    return result
```
この演算を実行すると、
* 開始：王様 [3, 4]
* 男性ベクトルを除去：[3-2, 4-3] = [1, 1]
* 女性ベクトルを追加：[1+2, 1+1] = [3, 2]
* 結果：[3, 2] （女王のベクトルと一致）

## 5. Word2Vecの応用

実際のWord2Vecシステムでは、
* 100-300次元のベクトルを使用
* 大規模なテキストコーパスから学習
* より複雑な意味関係も捉えることが可能
という特徴があります。

主な応用例としては、
* テキスト検索
* 文書分類
* 感情分析
* 機械翻訳
* 推薦システム
などが挙げられます。

## まとめ

Word2Vecは、単語の意味関係を数学的に表現する強力なツールです。
ベクトル演算によって単語間の関係性を操作できる点が特に興味深く、多くの自然言語処理タスクの基礎となっています。

この記事で示した2次元の例は概念理解のための簡略化されたものですが、基本的な原理は実際のシステムと同じです。
cscの作法 その565

# 概要
cscの作法、調べてみた。
練習問題やってみた。

# 練習問題
デスクトップのテキストファイルをgrepせよ。

# 方針
- テキストボックス使う。
- ボタン使う。
- 結果は、テキストボックスに一行表示。ファイル名：行目：一行


# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/d0fe4142-d495-4420-af2a-8201537cc7bb.png)

# サンプルコード

```

using System;
using System.Windows.Forms;
using System.Drawing;
using System.IO.Ports;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Text;

public class Searcher {
	protected readonly string[] Words;
	public Searcher(string[] words) {
		Words = words;
	}
	public virtual bool Search(string line) {
		return Words.Any(x => line.Contains(x));
	}
}
public static class GrepUtil {
	public static Func<string[], Searcher> SearcherFactory = words => new Searcher(words);
	public static IEnumerable<String> Grep(TextReader reader, params string[] words) {
		var searcher = SearcherFactory(words);
		string line;
		for (var i = 1; (line = reader.ReadLine()) != null; i++)
			if (searcher.Search(line))
				yield return i + ": " + line;
	}
}
class form1: Form {
	private Button button1;
	private TextBox textBox1;
	private TextBox textBox2;
	private TextBox textBox3;
	form1() {
		Text = "grep";
		ClientSize = new Size(500, 500);
		textBox1 = new TextBox();
		textBox1.Location = new Point(30, 20);
		textBox1.Size = new Size(300, 20);
		textBox1.Text = "ipv6";
		textBox2 = new TextBox();
		textBox2.Location = new Point(30, 70);
		textBox2.Size = new Size(300, 20);
		textBox2.Text = "ping6";
		button1 = new Button();
		button1.Location = new Point(300, 120);
		button1.Text = "grep";
		button1.Click += new EventHandler(button1_Click);
		textBox3 = new TextBox();
		textBox3.Location = new Point(30, 170);
		textBox3.Multiline = true;
		textBox3.Size = new Size(450, 320);
		textBox3.TabIndex = 2;
		textBox3.Text = "";
		textBox3.AutoSize = false;
		textBox3.WordWrap = false;
		textBox3.ScrollBars = ScrollBars.Both;
		Controls.AddRange(new Control[] {
			textBox1,
			textBox2,
			button1,
			textBox3
		});
	}
	private void button1_Click(object sender, EventArgs e) {
		string dpath =  Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "");
		DirectoryInfo di = new DirectoryInfo(dpath);
		FileInfo[] files = di.GetFiles("*.txt", SearchOption.TopDirectoryOnly);
		foreach (FileInfo f in files)
		{
			using(StreamReader sr = new StreamReader(f.FullName, Encoding.GetEncoding("Shift_JIS")))
			{
				string input = sr.ReadToEnd();
				using (var str = new StringReader(input))
				{
					List<string> result = GrepUtil.Grep(str, textBox1.Text, textBox2.Text).ToList();
					foreach (var item in result)
						textBox3.AppendText(f.FullName + " : " + item + "\r\n");
				}
			}
		}
	}
	[STAThread]
	public static void Main() {
		Application.Run(new form1());
	}
}





```

以上。
個人的備忘録：TLS/SSL証明書のエラー（ERROR 2026 (HY000)）の原因と解決策についてまとめてみた

## はじめに
AWS RDS (MySQL) に TLS/SSL 経由で接続しようとした際に発生するエラーについて、原因と対策をまとめました。

:::note warn
**個人の備忘録程度の走り書きとなっておりますが、温かい目で見守っていただければ幸いです。**
:::

特に、証明書の検証エラーが発生する場合の対応方法を詳しく解説します。

## 書こうと思ったきっかけ
このエラーは MySQL を RDS に接続する際に頻繁に発生し、解決方法が分かりにくいことが多いため、具体的な手順を整理しておくことが重要だと感じました。

また、環境によって適切な対処方法が異なるため、選択肢を提示する形でまとめました。

## エラーの概要
```
ERROR 2026 (HY000): TLS/SSL error: Certificate verification failure: The certificate is NOT trusted.
```
このエラーは、AWS RDS (MySQL) に TLS/SSL 経由で接続しようとした際に、証明書の検証に失敗したことを示しています。

## 解決策
エラーを解決するには、以下の3つの方法があります。

### 1. TLS/SSL 証明書のチェックを無効化する
MySQL に接続する際に `--ssl-mode=DISABLED` オプションを指定することで、証明書の検証をスキップし、非SSL接続を試みることができます。

#### 実行コマンド
```sh
/app # mysql -h $MYSQL_HOST -P $MYSQL_PORT -u $MYSQL_USER -p$MYSQL_PW --ssl-mode=DISABLED $MYSQL_DB
```
この方法は、RDS が内部ネットワークで動作している場合に有効であり、セキュリティ上問題がないことが多いです。

### 2. 正しい RDS の CA 証明書をダウンロードして利用する
もし TLS/SSL 接続が必須の場合は、AWS 公式の CA 証明書をダウンロードし、それを指定して接続する必要があります。

#### 証明書のダウンロード
```sh
wget -O /app/rds-ca.pem https://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.pem
```

#### 証明書を指定して MySQL に接続
```sh
/app # mysql -h $MYSQL_HOST -P $MYSQL_PORT -u $MYSQL_USER -p$MYSQL_PW --ssl-ca=/app/rds-ca.pem $MYSQL_DB
```
この方法により、正しく TLS/SSL 接続が確立されます。

### 3. MariaDB クライアントではなく MySQL クライアントを使用
Alpine Linux では `mysql-client` が MariaDB クライアントになっているため、`mariadb` コマンドを使うと解決する場合があります。

#### MariaDB クライアントで接続
```sh
/app # mariadb -h $MYSQL_HOST -P $MYSQL_PORT -u $MYSQL_USER -p$MYSQL_PW $MYSQL_DB
```

また、MySQL 公式クライアントを利用したい場合は、追加のリポジトリから取得する必要があります。

## どの方法を選ぶべきか？

| 方法 | メリット | デメリット |
|---|---|---|
| `--ssl-mode=DISABLED` を使用 | すぐに簡単に接続できる | TLS/SSL を使用しない |
| RDS の CA 証明書をダウンロード | 正しい TLS/SSL 設定ができる | 証明書の管理が必要 |
| `mariadb` コマンドを使用 | 追加の証明書が不要 | `mysql` コマンドが使えない |

## まとめ

**すぐに試すなら `--ssl-mode=DISABLED`**
```sh
/app # mysql -h $MYSQL_HOST -P $MYSQL_PORT -u $MYSQL_USER -p$MYSQL_PW --ssl-mode=DISABLED $MYSQL_DB
```

**TLS/SSL を有効にするなら AWS の証明書をダウンロード**
```sh
wget -O /app/rds-ca.pem https://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.pem
mysql -h $MYSQL_HOST -P $MYSQL_PORT -u $MYSQL_USER -p$MYSQL_PW --ssl-ca=/app/rds-ca.pem $MYSQL_DB
```

**MariaDB クライアントを使う場合**
```sh
/app # mariadb -h $MYSQL_HOST -P $MYSQL_PORT -u $MYSQL_USER -p$MYSQL_PW $MYSQL_DB
```

**最も簡単な解決策は `--ssl-mode=DISABLED` を指定する方法 なので、まずはこれを試してみるのが良いでしょう！**
“KISS”に書いてみよう〜☺️

## はじめに


「[読みやすいコードのガイドライン](https://gihyo.jp/book/2022/978-4-297-13036-7)」という本を読んでいる中で、

#### KISS

<br>
という原則が紹介されていましたので、記事にしてみたいと思います。

なお今回も前回の「[YAGNIの原則](https://qiita.com/fujihara_hideyuki/items/1e202e1b7fe95274e694)」の記事の時と同様、


Kotlinで書かれた本著の内容をDartに置き換えて書いてみました。

## KISSとは

KISSとは「**Keep it simple stupid**」[^1]の略語であり、
<br>

「**愚鈍なくらいシンプルにする**」[^2]

<br>
という意味からなる原則です。

先述の書籍の中では、
<br>

「自己満足のためにコードを複雑にしない」

<br>
といった踏み込んだことも言及されています。

例えば、
<br>

* ライブラリ、フレームワーク、デザインパターンなどを使いたいがために使用する

* フレームワークや標準ライブラリで提供されている機能を独自に再実装する

<br>
このようなことも避けるべきであると言及されており、

上記のようなことを避けて、

コードや設計を**素朴に単純に**していくことが重要であるとされています。


## KISSなコードとそうでないコード

ではここで、KISSなコードとそうでないコードを比較してみましょう。

::: note
なお今回のコードは

テストコードが使用するスタブのコードのため、

大元のコードから書いてみます。
:::

```dart
// 大元のコード
Stream<List<int>> getActualDataStream() {
  return Stream.fromFuture(Isolate.run(() => dataProvider.provide()));
}
```

上記のコードは、新しいアイソレートで`dataProvider.provide()`を実行し、

その結果をFutureとして受け取り、それをストリームに変換して返しています。

::: note
KISSではないコードについて確認される際は、

このコードの見た目や戻り値に注目していただければと思います。
:::

### KISSなコード

```dart
// KISSを踏まえたコード
Stream<List<int>> getStubDataStream() {
  return Stream.value([1, 10, 100]);
}
```

上記のコードは先述の`getActualDataSingle`関数に依存する

テストコードに対してスタブを提供する関数であり、

静的にテスト用の値を返すものです。

見た目からして大変シンプルであり、テストの際も楽になりそうですね。

### KISSではないコード

ではKISSではないコードだとどうなるのでしょうか？

これも見てみましょう。

```dart
// KISSではないコード
Stream<List<int>> getStubDataStream() {
  return Stream.fromFuture(Isolate.run(() => [1, 10, 100]));
}
```

見ていただけますと分かりやすいかと思われますが、

大元のコードと見た目がほとんど一緒ですね。

見た目の一貫性を重視してコーディングを行ったのでしょうが、

このコードだと、

「**テストで何を検証したいのか？**」

これが不明瞭になってしまっています。。。

本来これはテストの際のスタブのコードなので、

KISSに則ったコードのようにシンプルに振る舞いを模してあげればいいのですが、

これだと、
<br>

* 「Stream型の値を返す」

* 「Stream型に変換する処理をする」

* 「アイソレートで値を持ってくる」

<br>
上記のどれにフォーカスしているのかが分かりにくくなっていまいます...

このぐらいの文量ならまだしも、

これがより長大になってきた場合、
<br>

「あれっ、これって何をしたいスタブなんだろう...？」

<br>
そんなことが起こりそうな気がしてしまいます...😅



### さらに極端になると...

上記のコードでもその気配が何とはなしに感じられたかと思われますが、

ここでそれをより極端にしたものを書いてみます。

```dart
// KISSではないコードをより極端にしたもの
Stream<List<int>> getStubDataStream() {
  return Rx.range(1, 2).scan<List<int>>(
    (List<int> list, int _, int index) => [...list, list.last * 10],
    [1],
  ).asBroadcastStream();
}
```

ここまでくると、なんでスタブのコードを書いていたのかも分からなくなりますね😅

何をしているのか、何をしたいスタブなのか、

これが一読の限りや斜め読みで理解しづらい、

頭の中でイメージが湧いてきづらいコードになっていますね...😱

確かに端的でスマートな抽象度の高いカッコいいコードを書きたくなったりもしますし、

こういったことが求められるシーンもあると思われます。

ただ、殊に**可読性**という観点に立つと、

それは自分以外の誰か（**未来の自分**も含め）にとって

本当に**優しいコード**になっているのかというと、

ちょっと疑問符がついてしまいますよね。。。😭

色々な人がコードに触れ、メンテナンスもしていくので、

可読性も重視して書いていきたいですね☺️


## 参照

[読みやすいコードのガイドライン](https://gihyo.jp/book/2022/978-4-297-13036-7)

[^1]: 「Keep it simple stupid」ではなく「Keep it simple, stupid」の方が有名とのことですが、一部の文献では前者の方がオリジナルではないかとされているみたいです[^3]

[^2]: この考えはロッキード社の技術者であったKelly Johnson氏が提唱されたとのことです[^4]

[^3]: 「読みやすいコードのガイドライン」第1章28頁

[^4]: 同上
個人的備忘録: ECSコンテナからRDSに接続する方法とMySQLクライアントのインストールについて、自分なりに体系的にまとめた

## はじめに
この記事では、ECS コンテナ内で MySQL クライアントを使用して RDS に接続する手順を解説します。

:::note warn
**個人の備忘録程度の走り書きとなっておりますが、温かい目で見守っていただければ幸いです。**
:::

ECS 上で動作するアプリケーションが RDS を利用する場合に役立ちます。

## 書こうと思ったきっかけ
ECS を使用した環境で、RDS に正しく接続する方法がわからず困っている人が多いと感じました。

特に、環境変数の設定やセキュリティグループの設定が原因で接続に失敗するケースがよくあります。

本記事では、そうしたトラブルを防ぐための具体的な手順をまとめました。

## 1. RDS の接続情報を確認
RDS に接続するためには、以下の情報が必要です。

| 項目         | 説明                                                         |
|--------------|--------------------------------------------------------------|
| RDS ホスト名 | `MYSQL_HOST` 環境変数に設定されている                         |
| ポート       | `MYSQL_PORT=3306` (通常は 3306)                               |
| ユーザー名   | `MYSQL_USER` 環境変数 (例: myuser)                           |
| パスワード   | `MYSQL_PW` 環境変数 (基本的にAWS Secrets Manager から取得される)       |
| データベース名 | `MYSQL_DB` 環境変数 (例: mydatabase)                         |

### 環境変数の確認
まず、ECS コンテナ内で環境変数を確認してください。

```sh
/app # env | grep MYSQL
```

期待される出力例:
```sh
MYSQL_HOST=mydatabase.abcd1234.ap-northeast-1.rds.amazonaws.com
MYSQL_PORT=3306
MYSQL_USER=myuser
MYSQL_DB=mydatabase
MYSQL_PW=mypassword123  # AWS Secrets Manager から取得される場合、表示されない
```

## 2. MySQL クライアントをインストール
ECS のコンテナに MySQL クライアント (`mysql`) がインストールされていない場合は、`apk` を使用してインストールできます。

```sh
/app # apk add --no-cache mysql-client
```

## 3. RDS に接続
以下のコマンドを実行して、RDS に接続します。

```sh
/app # mysql -h $MYSQL_HOST -P $MYSQL_PORT -u $MYSQL_USER -p$MYSQL_PW $MYSQL_DB
```

または、環境変数を直接入力する場合:
```sh
/app # mysql -h mydatabase.abcd1234.ap-northeast-1.rds.amazonaws.com -P 3306 -u myuser -p mydatabase
```

成功すると、以下のような MySQL プロンプトが表示されます。

```sql
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 123
Server version: 8.0.39 MySQL Community Server - GPL

mysql>
```

## 4. RDS に接続できない場合の確認ポイント
もし RDS に接続できない場合、以下をチェックしてください。

- `MYSQL_HOST` の値が正しいか？
```sh
/app # echo $MYSQL_HOST
```

- RDS のセキュリティグループに ECS のセキュリティグループが許可されているか？
Terraform で ECS のセキュリティグループ (`ecs_sg`) から RDS のセキュリティグループ (`rds_sg`) にアクセス許可があるか確認。

- RDS のステータスが `available` になっているか？
```sh
aws rds describe-db-instances --query "DBInstances[*].DBInstanceStatus"
```
もし `stopped` になっていたら、起動する。

- RDS のパスワード (`MYSQL_PW`) を AWS Secrets Manager から取得する場合、正しく設定されているか？
```sh
/app # echo $MYSQL_PW
```
もし空欄なら、ECS のタスク定義で AWS Secrets Manager の参照が正しく設定されているか確認。

## 5. RDS のテーブル一覧を確認
RDS に接続できたら、データベースのテーブル一覧を表示してみましょう。

```sql
SHOW TABLES;
```

もし `migrate_app` でテーブルが作成されているなら、
`users, categories, questions, answers, choices, scores` などのテーブルが表示されるはずです。

## まとめ
- `env | grep MYSQL` で環境変数を確認
- `apk add --no-cache mysql-client` で MySQL クライアントをインストール
- `mysql -h $MYSQL_HOST -P $MYSQL_PORT -u $MYSQL_USER -p$MYSQL_PW $MYSQL_DB` で接続
- 接続できない場合は RDS のセキュリティグループやステータスを確認

この手順に従えば、ECS コンテナから RDS に接続できるはずです。
VSCodeでCopilotを使ってみた感想

# 題材
題材はAsabenehさんがGithub上に公開している「30DaysOfPython」
理由は数年前に途中までやっていたから
Pythonの勉強をしたいから
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3500655/7ea21f5b-5b82-4aa6-913b-991065f9c0b2.png)

# Github Copilot（GPT-4o）を使ってみた
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3500655/c084e8ea-88c2-4cf0-97ec-b9d3a0e6f894.png)

例えば、Day8「Dictionary」の講座で、Exercises: Day 8をVSCode上で以下のように問題文と回答を記述すると、次の問題文が自動で予測される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3500655/24553376-cce3-44aa-ab09-b77377b8df45.png)

Tabを押すと、回答まで予測してくれる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3500655/e611ab99-836d-4386-9804-42271fab0722.png)


何で予測できるのかわからないけれど、凄い！！
ちなみに実際のExerciseはこれ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3500655/73fe48b4-1a70-49d4-8a9f-d1142d998aee.png)

11.までの問題、回答まで予測してくれるし、11以降もなぜか自動で作成される！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3500655/16745bc6-e602-4dcf-b0a1-6e8bc9a19f79.png)

# 感想
プログラミングをする上でめっちゃ優秀なパートナーができた感じで、いろいろコードを書くのが楽になりそう。
反対に、Pythonは自分でコードを書いていないから、あまり覚えなさそう。
使い方としては、コードはGithub Copilotが書いて、何をしたいかなどは人間が考えていくようになるんかな。
今後は機械学習なども勉強したいと思っているので、いいパートナーができたみたいでよかった。
JVMで32GB以上のヒープ領域を割り当てる際の注意

# 挨拶
初めまして、日本システム開発株式会社の鈴木です。
技術者として更なる向上を目指すためQiitaアウトプットをする取り組みを行っています。
技術者としては経験が浅く発信内容はとにかく試したものの覚書になります。
今回は業務内でJVMに32GB以上のメモリを割り当てる必要が発生したため、その時の注意点と解決策を覚書していきます。

# 32GBの壁
　そもそもJVMに32GB以上のメモリを割り当てる際の問題点についてまとめます。
JVMに割り当てるメモリ（ここではヒープ領域のみを指す）はJVM引数の-Xms,-Xmxオプションで設定することができます。理論的にはここで指定するメモリサイズには上限がありませんので32GB以上を割り当てることができます。
　しかし、JVMのメモリ管理は圧縮OOPsという仕組みになっています。これは簡単にいうと、64bitシステムにおいてすべてのメモリアドレスを管理しようとするとアドレス部だけでメモリ領域を圧迫してしまうため、まずメモリ全体を8バイトごとに区切りアドレスはアドレス部×8が先頭であるとすることでアドレス部を圧縮するという考え方です。例えば0～255の256通りのアドレスを管理したいとなった時そのままでは8ビットのアドレス部が必要ですが×8で管理すれば0～31の32通り=5ビットで管理ができるのでアドレス部分が短くなってメモリの節約となります。この手法では代わりに、130のように8で割り切れないアドレスからデータの格納を行うことができず、例えば0から始めて12バイトのデータを格納したい場合圧縮をしなければ次のデータはアドレス13から始めることができますが、8バイト区切りの圧縮OOPsでは戦闘アドレスは8の倍数である必要があるため次のデータはアドレス16から始まります(13～16までは0で埋めることが一般的です)。そのため、メモリを隙間なく使うという観点では無駄が発生しますが、それよりもアドレス部の圧縮の方が恩恵が大きいという判断です。
　ここで32GBの壁の問題に話を戻します。圧縮OOPsではアドレス部を32bitにしアドレスを8倍にして管理することでアドレス部のメモリ節約を行っております。ではこの方式で表現できるアドレスの最大値は
 32bit×8B=2^32×2^3B=2^35B=34,359,738,368B≒32GBになります。つまり圧縮OOPsでは高々34GBがアドレス管理できる限界になるということで、これ以上のメモリを割り当てても圧縮OOPsでは参照することができません。
　しかし、冒頭で述べた通りJVMに-Xms,-Xmxオプションで32GB以上のメモリを割り当てることは可能です。ただし、そのままではメモリを管理しきれないためヒープ領域が32GBを超える場合**JVMは自動で圧縮OOPsを無効にしてしまいます**。結果、アドレス部の圧縮がされなくなりメモリを大量に割り当てたにもかかわらずメモリ使用効率が落ち、**見た目使用できるメモリが減ったように振舞う**ことがあります。これを本稿では32GBの壁と呼んでいます。

 # 対応策
 私の環境ではメモリ不足から38GBをJVMに割り当てようとしましたが、32GBの壁によりメモリ圧迫問題は改善しない可能性がありました。そこで、32GB以上は割り当てつつ圧縮OOPsを有効にする方針でJVMを設定しました。この方針では2通りの方法が考えられます。アドレス部を1ビット増やすかメモリの区切りを8から16にすることです（ビット単位の節約をしないといけないため、区切りは2のべき乗である必要があります）。今回は後者で対応しました。
　JVMでは圧縮OOPsの区切り1単位をアラインメント(Alignment)でと呼んでおりデフォルトは8Byteです。このサイズは-XX:ObjectAlignmentInBytesオプションで指定することができるため、今回は16byteで指定しました。
　設定後JVMを立ち上げヒープサイズをgcログから確認し、標準出力に警告が出ていないことをもって無事メモリが認識され圧縮OOPsが働いていることを確認しました（今回の環境ではJava内で他のログを出したりログレベルの変更が困難であったため標準出力のエラーログから確認しておりますが、gcログをDebugレベルにしてCompressedMemory情報を確認したり外部ライブラリから起動時にメモリ管理情報を出力する方が確認方法としては適切かと思います）。
　32GBの壁章で述べた通り、アラインメントを大きくすることはアラインメントに達しないために0埋めされる領域が増加するリスクを伴います。そのため、小さいデータを大量にメモリに格納するシステムでは今回の方法ではかえってメモリ効率が32GBを下回る可能性があります。これらの点を考慮してJVMのオプションを設定する必要があります
useReducer入門: useStateとの比較、使い分け

# はじめに
useReducerについての理解が浅かったため、その特徴をuseStateと紐づけて整理しました。

`useState` はシンプルで使いやすいですが、複数の状態や依存関係が増えると管理が難しくなります。  
そこで登場するのが **useReducer** です。  
この記事では、なぜ useReducer が必要なのか、どのように使うのかを解説します。

# useReducerとは？
useReducer は、React が提供するフックのひとつで、
状態とその更新ロジック（reducer関数）をまとめて管理するための仕組みです。

### **useReducer の基本的な流れ**
**reducer関数の定義**
現在の状態と「アクション」と呼ばれる更新指示を受け取り、新しい状態を返す
純粋関数を定義します。
```typescript: テーマを更新するreducer関数の例
function reducer(state, action) {
  switch (action.type) {
    case 'SET_THEME':
      return { ...state, theme: action.payload };
    default:
      return state;
  }
}
```

**useReducerの呼び出し**
useReducer に初期状態と reducer 関数を渡すと、
現在の状態と React が提供する dispatch 関数が返されます。

```typescript: useReducerの呼び出し例
// 初期状態を定義
const initialState = { theme: 'light' };

// 先程のステップで定義したreducer関数
function reducer(state, action) {
  switch (action.type) {
    case 'SET_THEME':
      return { ...state, theme: action.payload };
    default:
      return state;
  }
}

// 初期状態とreducerを引数にuseReducerを呼び出す
// useReducerから状態とdispatch(reducer関数を呼び出すための関数)を受け取る
const [state, dispatch] = useReducer(reducer, initialState);
```

**dispatch関数で更新リクエスト**
dispatch 関数にアクションオブジェクトを渡すと、
React が内部で reducer 関数を実行し、状態を更新して再レンダリングを行います。

# なぜuseReducerを使うのか？

### useStateによる状態管理の問題点

- **個別管理の限界**  
  `useState` は一つのプロパティの状態管理には適しています。  
  例えば、テーマの切り替えを管理する場合は以下のように実装できます。

  ```jsx
  const [theme, setTheme] = useState('light');
  
  // テーマを切り替える処理
  const toggleTheme = () => {
    setTheme(prevTheme => prevTheme === 'light' ? 'dark' : 'light');
  };

- **複数状態の管理が煩雑**
アプリケーションが大きくなると、テーマだけでなくユーザー情報、言語設定、その他多数の状態を個別に管理する必要が出てきます。
その結果、状態更新のロジックがコンポーネント内に分散し、どの更新がどの状態に影響を与えているかを把握するのが難しくなります。

### useReducerを使うメリット
- **更新ロジックの集中管理**
複数の状態を個別に管理するのではなく、状態更新のロジックを一箇所にまとめることで、
どのアクションがどの状態を更新するか明確に把握できます。

- **依存関係の追跡が容易に**
状態間の依存関係がある場合、すべての更新処理を一元化することで、
どの変更が他の状態にどう影響するかを容易に追跡・管理できます。

# useStateとの使い分け
### **useState の場合**
- シンプルな状態管理に最適
    **単一の状態**や**少数の状態**なら、以下のようにシンプルに実装できます

```typescript
const [theme, setTheme] = useState('light');

const toggleTheme = () => {
  setTheme(prevTheme => prevTheme === 'light' ? 'dark' : 'light');
};
```
### **useReducerの場合**
- 状態管理の一元化
**複数の状態を一つのオブジェクトで管理**し、更新ロジックを reducer 関数に集約できます。
全ての状態更新が一か所(reducer関数)に集約されるため、どのアクションがどの状態を更新しているかが明確になります。

# まとめ
### **useState**
- シンプルな状態管理に適しており、単一または少数の状態更新には手軽に利用できます
- 状態が複雑になった場合、更新ロジックが散在しやすく、管理が困難になります

### **useReducer**
- 複数の状態や依存関係を持つ場合でも、状態更新のロジックを一元化できるため、
コードの可読性と保守性が大幅に向上します
- reducer 関数で純粋な状態更新を実装し、dispatch 関数を通じて一元的に更新をリクエストする仕組みが特徴です

# 参考
[useState](https://ja.react.dev/reference/react/useState)
[useReducer](https://ja.react.dev/reference/react/useReducer)
個人的備忘録：Gorm の AutoMigrate() は何度実行しても問題ないのか？疑問に感じたため、自分なりに調べてみた

## はじめに

データベースのスキーマ管理は、アプリケーション開発において重要なポイントです。

:::note warn
**個人の備忘録程度の走り書きとなっておりますが、温かい目で見守っていただければ幸いです。**
:::

特に `AutoMigrate()` のような自動マイグレーション機能を使う場合、「何度も実行しても問題ないのか？」と疑問に思うことがあります。

## 記事を書こうと思ったきっかけ

Gorm の `AutoMigrate()` を使用したマイグレーション処理に関して、「何度も実行しても問題ないのか？」という疑問を持つ人が多いため、

その動作や安全な運用方法についてまとめることにしました。

## 結論: dbConn.AutoMigrate() の動作による

現在のコードは Gorm の `AutoMigrate()` を使ってマイグレーションを実行しているため、**「すでに適用済みのマイグレーションはスキップされる」** 仕様になっており、基本的に何度実行しても問題ありません。

**補足：現在のコードは、以下になります**

https://github.com/free-honda/skill-typing-back/blob/development/migrate/migrate.go

## dbConn.AutoMigrate() の動作
Gorm の `AutoMigrate()` は以下のように動作します。

- **テーブルが存在しない場合、新規作成する**
- **カラムが足りない場合、追加する**
- **既存のカラムのデータ型や制約の変更はしない**
- **既存のカラムやテーブルの削除はしない**

つまり、`AutoMigrate()` は**破壊的な変更（カラム削除・変更）をしない**ため、何度実行しても問題が発生することは少ないです。

## 問題になる可能性があるケース
以下のような場合は、毎回の実行で問題が発生する可能性があります。

### 1. `AutoMigrate()` 以外に `DROP TABLE` や `ALTER TABLE` を実行している場合
`AutoMigrate()` だけなら安全ですが、明示的に `DROP TABLE` や `ALTER TABLE` を使っている場合、データが消えたり、不整合が発生する可能性があります。

### 2. `AutoMigrate()` に依存せず、手動で SQL を実行している場合
以下のようなコードがあると、何度も実行するとエラーや不整合が発生する可能性があります。
```go
// すでにテーブルが存在するとエラーになる
 dbConn.Exec("CREATE TABLE users (id INT PRIMARY KEY, name VARCHAR(255));")
```

### 3. `AutoMigrate()` の前に `DROP TABLE` を実行している場合
```go
dbConn.Exec("DROP TABLE IF EXISTS users;") // データが消える
dbConn.AutoMigrate(&model.User{})
```
このようなコードがある場合、データが毎回削除されるので要注意です。

## 安全にするための対策

### 方法 1: `AutoMigrate()` で対応
現在のコードのままで `AutoMigrate()` を使うなら基本的に問題ありませんが、**Gorm の `AutoMigrate()` の仕様を理解し、破壊的な変更をしないことを確認する**必要があります。
```go
err = dbConn.AutoMigrate(
    &model.User{},
    &model.Category{},
    &model.Question{},
    &model.Answer{},
    &model.Choice{},
    &model.Score{},
)
```

### 方法 2: マイグレーションの実行を1回だけにする
**`migrate.lock` ファイルを使い、一度だけマイグレーションを実行するようにする**。
```go
package main

import (
    "fmt"
    "log"
    "os"
    "skill-typing-back/db"
    "skill-typing-back/model"
)

func main() {
    if _, err := os.Stat("/app/migrate.lock"); err == nil {
        fmt.Println("Migrations already applied, skipping.")
        return
    }

    dbConn := db.NewDB()
    if dbConn == nil {
        log.Fatal("データベースの初期化に失敗しました")
    }
    log.Println("データベースの初期化に成功")

    sqlDB, err := dbConn.DB()
    if err != nil {
        log.Fatal("Failed to get DB connection:", err)
    }
    defer sqlDB.Close()

    fmt.Println("Starting migration...")
    err = dbConn.AutoMigrate(
        &model.User{},
        &model.Category{},
        &model.Question{},
        &model.Answer{},
        &model.Choice{},
        &model.Score{},
    )
    if err != nil {
        log.Fatal("Migration failed:", err)
    }

    f, err := os.Create("/app/migrate.lock")
    if err != nil {
        log.Fatal("Failed to create migrate.lock:", err)
    }
    defer f.Close()

    fmt.Println("Successfully Migrated")
}
```

## まとめ
`AutoMigrate()` は基本的に**何度実行しても問題なく、idempotent** であるため、特に気にせず使える点は便利だと感じました。  

:::note info
***ただし、**より安全に運用するなら `migrate.lock` を活用して、一度だけ実行する仕組みにするのがベスト** だと思います。***
:::

**個人的には、まず `migrate.lock` を使う方法がシンプルで実装しやすく、かつ安全なので、この方法を試してみるのが良さそう** だと感じました！
mBot2でつくるプログラミング環境

# はじめに
mBot2/mBlockを使ってプログラミング環境を作ってみた。

## やりたいこと
PCを使うことなくプログラムする環境をmBlockで作ってみた。
mBlockは確かに簡単だけれど、PCやスマホでの操作が必要。

PCを使うことなくプログラムする
・どうしよう？！
・そうだ！
・昔の紙プログラムに回帰しよう！
・mBot2は色が認識できたな！？
ということで作ってみた。
## プログラムの概要
変数一覧
![変数一覧.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4017908/71f9de97-9a37-45b4-a44f-b75c3a839086.png)

リスト宣言
![リスト一覧.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4017908/027789b1-196b-4e9d-affb-f463822e7186.png)

プログラムは、３つのブロックで構成されている。
・初期化ブロック
![mblock_block_初期化ブロック.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4017908/38d7ca1b-9f85-4027-8c07-4af0763a5b4b.png)

・プログラミングブロック
![mblock_block_プログラミング.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4017908/8ecefea2-9e28-4cc5-b08f-277120e4b28a.png)

・プログラム実行ブロック
![mblock_block_プログラム実行.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4017908/c0acd377-ab3d-457c-ab6c-4c3247825508.png)

license: CC BY-SA 4.0

### 初期化ブロック
1.イベント：CyberPiが起動した、でこのブロックを開始
2.変数に初期値を入れていく（この値は、動作の定義した定数値）
3.プログラムを格納するリスト変数を全削除
4.音で知らせるので音量を100%に
5.準備完了を表示
して終わり

### プログラミングブロック
Aボタンを押すとプログラミングモードになる。
クワッドrgbセンサーを使って、色紙の色を識別、動作を覚えていく。

1.イベント：Aボタンが押されたとき、でこのブロックを開始
2.クワッドrbgセンサーのキャリブレーション、モードを設定
3.プログラムを格納するリスト変数を全削除する
4.あらかじめ設定したプログラムの最大数でループ
4-1.色を見つけるために前進
4-2.右へ行く色、ここでは緑か判定し、緑色紙の時は右へ行くことを一時的に覚える
4-3.左へ行く色、ここでは青か判定し、青色紙の時は左へ行くことを一時的に覚える
4-4.前へ行く色、ここでは赤か判定し、赤色紙の時は前へ行くことを一時的に覚える
4-5.前へ行く色、ここでは黒か判定し、黒色紙の時は後へ行くことを一時的に覚える
4-6.前へ行く色、ここでは白か判定し、白の時はプログラムすることを止める
4-7.設定がないときは、LED虹色表示
4-8.一時的に覚えた動作をプログラムを格納するリスト変数に追加する
5.終わったら音を鳴らし、プログラム完了メッセージを表示
して終わり

### プログラム実行ブロック
Bボタンを押すとプログラム実行モードになる。
覚えた動作に従って、mBot2を動かす。

1.イベント：Bボタンが押されたとき、でこのブロックを開始
2.クワッドrbgセンサーのキャリブレーション、モードを設定
3.ループ変数の設定
4.あらかじめ覚えたプログラムの最大数でループ
4-1.今回の動きを一時的に覚え、プログラム番号を表示
4-2.右へ行くときは、mBot2を右折させ一定距離動かす
4-3.左へ行くときは、mBot2を左折させ一定距離動かす
4-4.前へ行くときは、mBot2を前進方向に一定距離動かす
4-5.後へ行くときは、mBot2を後進方向に一定距離動かす
4-5.ライトをつけるときは、LED虹色表示
4-6.1回ずつ区切りの音をならす
5.終わったら全停止
して終わり

## ちょっとしたポイント
### 定数の利用
プログラム言語を使う人なら、避けてとおりたいマジックナンバー。
変数を定数のように使うことで、変数名に意味を持たしています。起動時に変数を初期化することで、定数のように使えます。（変更もできてしまうのが難点）

### プログラム量の可変可
白色を最後だとすることで、プログラムできる量を可変にした。
無限にならないようプログラム数の最大もいっしょに定義。

### そもそものはなし
学校でプログラミングが始まったとはいえ、PCやタブレットを使うことが、ちょっとした障害。
まず、プログラムの基本、命令を順序だて並べるということと、視覚的なわかりやすさで色紙をチョイス。
※色紙は薄いと走っているときに、しわになったり、破れたり。色画用紙とか丈夫なものがおすすめ。

色紙でなくても、プラスチックプレートなどでも可能。
色紙にユニバーサルデザイン（矢印や▲などのマーク）を取り入れると、なおヨシ！
※マークの影響を受けにくいよう、ランダム検出にはしていますが、たぶん、すみっこにマークしたほうが良いです。

## 最後に
CC BY-SA 4.0（著作者の情報とCCライセンス継承はお願いします。商用利用・改変・再配布は問題なし）です。
【Rails】form_with のオプションの指定方法について

# はじめに

こんにちは。アメリカにて独学でエンジニアを目指している者です。

以前の記事にて`form_with`のオプションは`model:@user`という指定方法を説明しましたが、Railsが自動で判断してcreateかupdateのどちらかのアクションを割り当てるというものでした。

しかし、当然Userのviewでしか使用できないためsessionコントローラーでログインページを作成するとなった場合には使用できません。

そこで本日は、`model:@user`を使う意義をあらめて確認したのち、今回のsessionコントローラーの場合はどのように定義をするのがよいかについて説明していきたいと思います。

## model: @userを使う意義

もし`model: @user`と書いた場合、Railsは以下のような振る舞いを行います。

1. `@user`という変数に格納されたActiveRecordオブジェクト（例えば、Userモデルのインスタンス）とフォームを関連付ける。
2. フォームのフィールドとモデルの属性が1対1で対応するため、フォームで入力された値がモデルの属性に自動的に紐づく。
3. バリデーションエラーがある場合などには、フォームとモデルが連携し、エラーメッセージの表示やハイライトが可能になる。

`model: @user`は、主に以下のケースで有用です。

- 新規ユーザー登録フォーム（`@user`を新規作成し、`User.new`で生成したオブジェクトと関連付けてフォームを表示）
- ユーザー情報編集フォーム（すでに保存されている`@user`を取得し、フォームを通じて更新）

このように、**モデルの属性とフォームの入力欄を対応付け、フォーム送信後にモデルインスタンスを作成・更新するという流れが中心**となります。

また、今回のようにSessionControllerでログイン機能を実装する場合は、そもそも`@user`というインスタンス変数が定義されていませんし、`@session`のようなものをActiveRecordで管理することも通常はありません。そのため、ログインフォームに`model: @user`を使う意義がなく、エラーとなってしまいます。

## ログインフォームの特徴

ユーザーがアプリケーションにログインするとき、基本的には以下のステップを経ます。

1. ユーザーのメールアドレスとパスワードを入力する。
2. 送信ボタンが押されると、サーバー側にパラメータがPOSTされる。
3. サーバー側でメールアドレスとパスワードが正しいかチェックする。
4. セッションを作成し（または更新し）、そのユーザーがログイン済みであることを保持する。

この一連の流れの中では、データベースに新規レコードを作成したり、モデルのレコードを更新するといった操作は基本的に行いません。あくまで既存のユーザーに対して"ログイン"という操作を行うだけだからです。

## SessionControllerにおける`form_with`

一方、`SessionController`はセッションを扱うコントローラです。セッションは、そもそもデータベースのレコードではありません。ブラウザとサーバー間でやり取りされる一時的な情報であり、Cookiesなどを通じてログイン状態を保持します。

したがって、**セッションコントローラで`model: @user`と書いてしまうと、そもそも存在しない`@user`を参照しようとするため、意図した動作になりません。**また、以下の点で利点がありません。

- ユーザーモデルを新規作成・更新しない
- セッション用のオブジェクト（`@session`のようなもの）をActiveRecordで持つことは通常ない

そのため、セッションコントローラでログインフォームを扱う際は、`url:` オプションにログイン処理のパスを指定し、`scope:` でパラメータをどのようにネストするかを指定します。

例えば、

```erb
<%= form_with(url: login_path, scope: :session) do |f| %>
  <%= f.label :email %>
  <%= f.email_field :email %>

  <%= f.label :password %>
  <%= f.password_field :password %>

  <%= f.submit "ログイン" %>
<% end %>
```

この場合、フォーム送信時のパラメータ構造は下記のようになります。

```ruby
params = {
  session: {
    email: "ユーザーが入力したメールアドレス",
    password: "ユーザーが入力したパスワード"
  }
}
```

コントローラでは、`params[:session][:email]` と `params[:session][:password]` を使用してログイン認証処理を行う、という流れになります。

## まとめ

- **ログインフォームでは、モデルのレコードを作成・更新しないため、`model: @user`を使う必要がない。**
- セッションコントローラでは、セッションの作成や削除などを行うだけで、ActiveRecordのモデルインスタンスとは直接連動していない。
- そのため、`form_with`のオプションとして`url:`や`scope:`を使って明示的にURLとネストキーを指定し、送信されたパラメータをログイン用に扱う。

これが、SessionControllerで`form_with(model: @user)`が使えず、`form_with(url: login_path, scope: :session)` のように書かれている理由です。ログイン処理の流れを把握し、モデルを不要とするケースではこうした書き方がRails的にも自然であると言えます.
2つあるプロフィールアイコンを半分ずつ使う

```python
#!/usr/bin/env python3
# filename
# vertical_split_merge.py

from PIL import Image

# 入力ファイルのパス
file_a = "A.png" 
file_b = "B.png" 

# 画像を読み込む
image_a = Image.open(file_a)
image_b = Image.open(file_b)

# 画像を縦方向に等分に分割する関数
def split_image_vertically(image):
    width, height = image.size
    left_box = (0, 0, width // 2, height)   # 左半分
    right_box = (width // 2, 0, width, height)  # 右半分
    left_part = image.crop(left_box)
    right_part = image.crop(right_box)
    return left_part, right_part

# AとBの画像をそれぞれ縦方向に分割
a_left, _ = split_image_vertically(image_a)
_, b_right = split_image_vertically(image_b)

# 左右のパーツの高さを一致させるため、共通の高さを決定（小さい方に合わせる）
common_height = min(a_left.height, b_right.height)

# 両方の画像パーツを上部から共通の高さでクロップ
a_left_cropped = a_left.crop((0, 0, a_left.width, common_height))
b_right_cropped = b_right.crop((0, 0, b_right.width, common_height))

# 結合後の画像サイズを計算
new_width = a_left_cropped.width + b_right_cropped.width
new_height = common_height

# 結合後の画像用のキャンバスを作成（背景は黒）
new_image = Image.new("RGB", (new_width, new_height))

# Aの左部分とBの右部分を貼り付け
new_image.paste(a_left_cropped, (0, 0))                  # 左側にAの左部分
new_image.paste(b_right_cropped, (a_left_cropped.width, 0))  # 右側にBの右部分

# 結果を保存（PNG形式で保存。JPEG形式で保存する場合は、output_file を "output.jpg" に変更）
output_file = "output.png"
new_image.save(output_file)

print("新しい画像が保存されました:", output_file)
```
![output.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4017910/2c0e6993-e6f1-4c42-a5c7-8f35e5723172.png)
![A.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4017910/6e27fd83-0e6b-4709-ada9-c1408661e942.png)
![B.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4017910/6d729dbe-b421-41ea-b479-633c9a72c359.png)
重要な更新: 新しい強化されたセキュリティデータスペースを採用していない組織の場合


+ [Important Update: To any org the hasn’t adopted the new enhanced security data spaces](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000KDk2s)

データスペース対応の Data Cloud 機能へのアクセスを維持するには、組織は 2025 年 3 月 31 日までに、強化されたセキュリティ データスペースを有効にし、新しい標準権限セットをユーザーに割り当てる必要があります。

# どのようなアクションを取る必要がありますか? 

「Data Cloud を拡張セキュリティ データ スペースに更新する」の手順に従って、新しい標準権限セットを構成し、拡張セキュリティ データ スペースをオンにします。組織がデフォルトのデータ スペースのみを使用している場合でも、このアクションは必須です。

 

上記の手順をすでに完了している場合は、それ以上のアクションは不要であり、このメッセージは無視できます。

# まだアクションを起こす必要があるかどうかを確認するにはどうすればよいですか?

権限セットが更新されたことを確認するには、次の点を確認してください。 

1. すべてのユーザーには、新しい Data Cloud 標準権限セットまたはそこから派生したカスタム権限セットが割り当てられます。従来の権限セットに割り当てられているユーザーはいません。
2. データ スペースは、ユーザーに割り当てられた権限セットの一部です。
3. 「データ クラウド設定」>「機能管理」>「データ スペース」から 「データ スペース セキュリティの強化」を有効にしました。

# 何も行動を起こさなければどうなるのでしょうか? 

2025 年 3 月 31 日以降、組織では強制移行が発生しますが、これにより一部の組織で Data Cloud のデータ可視性の問題が発生する可能性があります。

# さらに詳しい情報を得るにはどうすればいいですか? 

さらに質問がある場合は、「新しいデータ クラウド権限セットへの移行」のリリース ノートを確認してください。Salesforce ヘルプを通じてサポートにケースを開くこともできます。
PyCharmで使われなくなったインタープリターを削除する方法

## 課題

PyCharmを使っていると、古いプロジェクトを削除しても、インタープリターが [Invalid: 無効] と表示されたまま残ることがあります。

![pycharm01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208980/665b61a5-4a3e-4aaf-859b-df0b12f2e414.png)

PyCharm は時々「無効な Python インタープリターが選択されました」と表示します。これは、削除したはずの Python インタープリターが大量に残ってしまうためですが、PyCharm はこれを自動的に削除してくれません。

## 解決策


PyCharm には無効なインタープリターを自動削除する機能がないため、手動で削除する必要があります。

1. [Settings] > [Project: プロジェクト名] > [Python Interpreter] を開く
1. 右上の⚙（設定アイコン）をクリックし、[Show All] を選択
1. 一覧から [Invalid] と表示されているインタープリターを選択し、削除
![pycharm02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208980/0ece37d1-2a21-4cdd-a456-eba821095029.png)
【ブランチ戦略】gitlab-flowを理解と実践へ向けて

# 理解してみる
## GitLab Flowとは
- production、pre-production、main、featureからなるブランチ戦略である
- 主なブランチは「main」で、機能ブランチをマージし、必要に応じてプレプロダクションやプロダクションブランチを使用

> ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654759/98c0154f-2979-480a-89ab-84305cce9fc9.png)
> [引用：GitLab flow とは](https://www.zoma-blog.com/post/other/git/20230216_git_strategy_gitlab_flow/)

## 開発の進め方
1. **ブランチ作成**
`main`ブランチから`feature/NAME`ブランチを作成

2. **開発とマージリクエスト**
開発完了後、`main`ブランチへマージリクエストを作成

3. **ステージング環境デプロイ**
mainブランチをステージング環境にデプロイし動作確認

4. **本番前準備**
`main`から`pre-production`へマージリクエストを作成しテスト

5. **本番リリース**
`pre-production`から`production`へマージリクエストを作成しデプロイ

## ベストプラクティス

1. **featureブランチの使用**
    - すべての新しい作業（機能追加やバグ修正）に機能ブランチを作成し、mainブランチをクリーンに保つ
 
2. **mainブランチのプロダクション対応**
    - mainブランチは常にプロダクションにデプロイ可能な状態を保つ

3. **マージリクエストの必須化**
    - すべての変更はマージリクエストを通じてmainに統合される

4. **必須のコードレビュー**
    - すべてのマージリクエストは少なくとも1人のチームメンバーによるレビューを受け、コード品質を維持する

5. **自動テストの実施**
    - GitLabのCI/CDパイプラインを使用して、機能ブランチとmainブランチで自動テストを実行する

6. **短期間の機能ブランチ**
    - 機能ブランチは短期間で作成・マージし、mainブランチとのコンフリクトを最小限に抑える

7. **明確なブランチ命名**
    - ブランチ名に一貫した命名規則を採用し、例えばfeature/123-login-fixのようにする

8. **issueとのリンク**
    - マージリクエストを対応するissueにリンクし、開発進捗を追跡可能にする

9. **プレプロダクションブランチの活用**
    - 必要に応じてプレプロダクションブランチ（例：test、acceptance）を追加し、mainからのマージでテストを行う

9. **ホットフィックスの管理**
    - 緊急のバグ修正にはmainからホットフィックスブランチを作成し、修正後すぐにmainにマージする

# Githubでの実践に向けて
:::note warn
導入したものがあれば追記予定
:::

## 設定した方が良いこと
1. ブランチ保護ルールの設定
    - プルリクエストレビューを必須化
    - すべてのチェックが通過することを必須化
    - フォースプッシュとブランチ削除を防止
    - プルリクエストの承認数を指定

2. Github Actionsを使ってCI/CDを組む
1. 明確な記述とレビュアーの割り当て
    - プルリクエストには詳細な説明を書き、特定のレビュアーを割り当てます。レビュアーはコードコメントや議論を通じてフィードバック1. 議論の解決
    - すべての議論が解決されるまでプルリクエストをマージしないようにする

1. PR-Agnetを使ったAIコードレビュー
    - [PR-AgentとBedrockでGitHubのPRをAIにレビューしてもらう](https://dev.classmethod.jp/articles/shuntaka-pr-agent-with-bedrock/)
    - [PR-Agent を使って Pull Request をAIレビューしてみた。（日本語対応もしてみた）](https://tech.layerx.co.jp/entry/2023/09/01/102612)
    - [pr-agentを入れてみるテスト](https://qiita.com/Jey/items/2c50e4c6e798d6cf97c7)
MacOSをAWSで構築したら料金が思いのほか高かった話

# はじめに
MacOSをAWSで構築してみたら思いのほか料金がかさんだので、参考のために費用を公開します！！
こんな人におすすめ！
* MacOSをお試しで使ってみたい！
* IOSアプリをビルドするためだけにMacOSが必要！

# 前提
* 合計コスト：**$253.45** (37,821円 ※149.22円/ドル)
* 使用サービス：専有ホスト＋EC２インスタンス
* 使用期間：一か月弱
* EC２インスタンス情報：
    * インスタンスタイプ：mac1.metal
    * ストレージタイプ：gp3
    * ストレージサイズ：400 GiB

インスタンスは使用しない間は停止し、専有ホストは1日が過ぎるとすぐにリリースしてました。
日別にかかった料金は以下の通りです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4007207/a70ab96f-43a9-4dc2-af99-a09743821c81.png)



# サービス別料金と内訳
### サービス別料金
![スクリーンショット 2025-02-22 101403.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4007207/8fada361-ba13-43f4-bf76-819c14afad5b.png)

専有ホスト＋EC２インスタンスのコンピューティングの費用が約9割を占めています。

### 内訳
赤は無料枠、青は主にかかった費用になります。
![screencapture-us-east-1-console-aws-amazon-billing-home-2025-02-22-10_20_05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4007207/13a3d2b7-d82f-4901-b106-aeb30ecaaba9.png)

##### 青①
専有ホストにかかる費用になります。
合計の約8割を占めていますね。
専有ホストは一日を過ぎないとリリースができません。
そのため短時間での使用であったとしても確定で一日分の費用が発生してしまうため、**効率的な使用方法を考える必要があります**。

##### 青②
ストレージにかかる費用になります。
多くはないですが、円換算で2,372円なので無視できません。
無料枠で30 GB-Mo用意されていますが、全く足りてないですね。

##### 青③
おそらくデータ転送にかかる費用になります。
chatGPT曰く、「AWSのデータセンターからインターネットや他のリージョンにデータを送信する際の通信量に対する料金」とのことです。
こちらも無料枠で100GB用意されていますが、大幅にオーバーしています。
また10TBを超えた際は別の料金レートで換算されるようなので、注意が必要ですね。


### 無料枠について
![スクリーンショット 2025-02-22 101321.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4007207/9e6a69d5-745d-4349-9230-3f22749ac150.png)

##### 赤③
EC２インスタンスのアクティブ時間にかかるコストは無料枠で十分賄いきれました。（無料枠は年合計の10%程しか使用していない）

# まとめ

* いくら短時間の利用であっても、専有ホストは必ず一日分のコスト(約4000円)がかかるので、料金がかさんでしまう。
* 専有ホスト以外のコストについては無料枠で十分賄える。

# 最後に
MacOSを利用するときは必ず一日分の利用が見込まれるという方にはおすすめです！
また小規模ビジネスであれば、**300 USD 相当のクレジットの提供を受けることもできる**ので、キャンペーンをうまく使えばお得に利用することは可能です。
（AWSよりクレジット申請のメールが届きます。）

とはいえ、2025/2/22時点でMac miniが94,800円(税込)～で購入できるので、**利用時間が1か月以上を超えてくる場合はハードウェアを購入したほうがお得ですね！！**