OmniAICreator/Qiita-1.07M huggingface dataset:
windows11で、sketchup6 その29

# 概要
windows11に、sketchup6を入れてみた。
rubyで、3Dを書く。
hipoly0、見つけたので、やってみた。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/cc11af2f-cbb4-4ff0-8516-38a29e0cf13d.png)

# サンプルコード

```

def hipoly0
	model = Sketchup.active_model
	entities = model.active_entities
	p1 = Geom::Point3d.new 0, 0, 0
	p2 = Geom::Point3d.new 10, 10, 10
	radius = p2.distance(p1)
	dtheta = dphi = 360.0 / 30
	-90.step(90, dtheta) do |theta|
		0.step(360, dphi) do |phi|
			pts = []
			x = radius * Math::cos(theta.degrees) * Math::cos(phi.degrees)
			y = radius * Math::cos(theta.degrees) * Math::sin(phi.degrees)
			z = radius * Math::sin(theta.degrees)
			pts << (p1 + [x, y, z])
			x = radius * Math::cos((theta + dtheta).degrees) * Math::cos(phi.degrees)
			y = radius * Math::cos((theta + dtheta).degrees) * Math::sin(phi.degrees)
			z = radius * Math::sin((theta + dtheta).degrees)
			pts << (p1 + [x, y, z])
			x = radius * Math::cos((theta + dtheta).degrees) * Math::cos((phi + dphi).degrees)
			y = radius * Math::cos((theta + dtheta).degrees) * Math::sin((phi + dphi).degrees)
			z = radius * Math::sin((theta + dtheta).degrees)
			pts << (p1 + [x, y, z])
			if theta > -90 && theta < 90
				x = radius * Math::cos(theta.degrees) * Math::cos((phi + dphi).degrees)
				y = radius * Math::cos(theta.degrees) * Math::sin((phi + dphi).degrees)
				z = radius * Math::sin(theta.degrees)
				pts << (p1 + [x, y, z])
			end
			#pts.uniq!
			begin
				entities.add_face pts
			rescue
			end
		end
	end
end

```

以上。
Railsチュートリアル5章 雑まとめ（超個人向け）


記憶定着のための、超個人記録です。


# Rails tutorial 5章
## genelrate controller
※5章の内容ではないですが、忘れていたのでこちらに
```terminal
$ rails g controller Users new
```
このようにコントローラーを生成した。
その際、newと指定しておくことでnewのviewページが作成され、newメソッドも同時に定義された状態のコントローラーができる


## パスの定義
### routesファイルや利用できるヘルパー
```ruby:config/routes.rb
root '<controller名>#<メソッド名>'
get  '/<path>', to: '<controller名>#<メソッド名>'
# asを利用した記載
get  '/<path>', to: '<controller名>#<メソッド名>', as: '<path名>'
```
rootに定義したものは、`root_path` or `root_url` などのヘルパーで呼び出せる。
pathは相対パス（/）、urlでは絶対パス（https://~）が組み込まれる。基本的にリダイレクトの際のみurl指定をする。
→ どのブラウザでも、基本どちらも動くが、httpの原則にし違うとそうなる、んだっけ？（→確認！）
asの指定がなければ、最初のパスからヘルパーが定義される。
asの指定をすると、それで呼び出せる。
```ruby:asの例
get  '/init', to: 'sample#init' # init_path
get  '/init', to: 'sample#init', as: 'test' # test_path
```
ちなみに、プロジェクトのルートディレクトリでrails routesと入力するとルーティングの一覧が表示される。

### erb
erbでも、`root_path`のような記述が利用できる
link_toヘルパーの第二引数にそれを指定できる
```erb:サンプル
<%= link_to 'Init', init_path %>
# 以下のように変換される
<a href='/init'>Init</a>
```
開発者ツールで見てみる(aboutの例)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2704095/ccd84908-8bd3-4632-8ce0-31abafe9d87e.png)

## パーシャル
erbを別ファイルに切り出せる。
ファイル名は、`_header.html.erb`のようにアンダースコアから始める。
また、erbファイルなので`<%%>`のような記載でも切り出しておける。

## アセットパイプライン
### 標準的なassetsディレクトリ
railsには基本的に、
`app/assets`
`lib/assets`
`vendor/assets（デフォルトではなし）`
の三つのassetsディレクトリがある。上から順に、
* プロジェクト固有のassets
* 開発チームなどで共有されるassets
* サードパーティー（他企業）向けassets
となっている。

### マニュフェストファイル
マニュフェストファイルにより、どのようにassetsを一つにまとめるかを定義できる。
※一つにまとめてくれるのはspRocketsというGem
実際に中身を見てみると、
```css:app/assets/stylesheets/application.css
/*
 * ~略~
 *= require_tree . // このディレクトリ配下のファイルを全てapplication cssに含める
 *= require_self // このファイル自身も含む
 */
```
全体は以下で定義され、上記cssも含まれていることがわかる。
```js:app/assets/config/manifest.js
//= link_tree ../images 
//= link_directory ../stylesheets .css　# assets/stylesheets はここに記載あり
//= link_tree ../../javascript .js
//= link_tree ../../../vendor/javascript .js
```

### プリプロセッサエンジン
railsは、assetsにまとめたファイルなどをブラウザに配信できるよう、拡張子を見てプリプロセスを実行してくれている。erbならerb向けのプリプロセッサ、scssならSass向けのプロセッサを利用し、ブラウザで表示できる形にしている。

### 本番環境での効率
人間的に読みやすいscssのファイル記述そのままだと、ブラウザやpc的には効率的でない場合が多々ある。（pc的には不要なインデントやファイル分割など。）
しかし、アセットパイプラインにそれらをまとめておくことにより、事前に読み込み・最適化（ファイルサイズの最小化など）をしてくれるため、そのトレードオフを考える必要がなくなる。

#### どこで事前コンパイルしているか？
本番環境等では、サーバーで動かそうとするとこのコンパイルを忘れエラーが出ること（が私の場合多い）
このことからも、スタートする前にコンパイルする必要があるとわかる。
rails newで作成されるdockerファイルでは以下のように記載があり、特にこちらで気にしなくてもやってくれている。
```Dockerfile
# Precompiling assets for production without requiring secret RAILS_MASTER_KEY
RUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile
```
また、dev環境では自分でコマンドを打たなくても読み込んでくれている。
（rails s で env が develop だとそうしてくれているとか、、、？要確認）
その結果、本番環境で初めて「プレコンパイルして！」というエラーに出会うわけである。

## scss
入れ子構造で、よりシンプルにcssを記載できる。
クラスやタグの入れ子は内部に書けばよく、アクションなどによるスタイルは&:~というように記載する。
```scss:雑サンプル
header {
    padding: 10px, 20px;
    h1 {
        color: white;
    }
    .logo {
        &:hover {
            color: black;
        } 
    }
}
```

他、変数定義もできる
```scss
$light-gray: #777;

header {
    color: $light-gray;
}
```
MSX BASIC の PRINT で余計な空白を入れずに数値を出力する

今回は、[WebMSX](https://webmsx.org/) で動作を確認した。

# まずは何も工夫せずに出力してみる

[PRINT 命令](http://ngs.no.coocan.jp/doc/wiki.cgi/datapack?page=2%C9%F4+3%2E13+%A5%B9%A5%C6%A1%BC%A5%C8%A5%E1%A5%F3%A5%C8#PRINT)を用いると、指定した数値をテキスト画面に出力することができる。
しかし、なぜか数値の前後に勝手に空白が入ってしまう。

```text
10 N=42
20 PRINT "|";N;"|"
```

![何も工夫せずに出力した結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/e0b83af6-45b0-4702-afd9-e74d96b9ef90.png)

# 数値を文字列に変換してから出力してみる

[STR$ 関数](http://ngs.no.coocan.jp/doc/wiki.cgi/datapack?page=2%C9%F4+3%2E13+%A5%B9%A5%C6%A1%BC%A5%C8%A5%E1%A5%F3%A5%C8#STR$)を用いると、引数として渡した数値を文字列に変換することができる。
これを用いて数値を文字列に変換したものを `PRINT` 命令で出力することで、数値の後ろに余計な空白を入れられるのを回避できた。
しかし、これを用いても、数値の前には空白が入ってしまった。

```text
10 N=42
20 PRINT "|";STR$(N);"|"
```

![数値を文字列に変換してから出力した結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/7121e208-e2a4-4925-8891-f60e82beb7df.png)

# 余計な空白を直接消して出力してみる

[MID$ 関数](http://ngs.no.coocan.jp/doc/wiki.cgi/datapack?page=2%C9%F4+3%2E13+%A5%B9%A5%C6%A1%BC%A5%C8%A5%E1%A5%F3%A5%C8#MID$%20%E2%91%A0)を用いると、文字列の中の指定した部分を取り出した新しい文字列を得ることができる。
これを用いて、`STR$` 関数の変換結果の最初の余計な空白を除いた部分を取り出し、出力する。

```text
10 N=42
20 PRINT "|";MID$(STR$(N),2);"|"
```

![余計な空白を直接消して出力した結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/2544cca7-ac39-4b01-9918-ebe6eee526be.png)

一見、うまくいったように見える。
しかし、実は**負の数を出力・変換する場合は、前に余計な空白は入らない**のである。
そのため、この実装では、負の数の符号が消え、間違った出力になってしまう。

```text
10 FOR N=-3 TO 3
20 PRINT "|";MID$(STR$(N),2);"|"
30 NEXT N
```

![余計な空白を直接消して出力した結果 2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/dfd6e4df-32c8-4e12-b875-f105289f9602.png)

非負の数値しか扱わない場面では、この実装でもよいと考えられる。

# 負の場合は最初の文字を消さないようにする (完成)

前章の方法では、負の場合は符号が消えて間違った結果になったが、負でない場合は良い結果が得られた。
そこで、負の場合のみ最初の文字を消さないようにすればよい。

MSX BASIC の[関係演算子](http://ngs.no.coocan.jp/doc/wiki.cgi/datapack?page=2%C9%F4+3%2E3+BASIC%A4%CE%CA%B8%CB%A1#p14)は、真のとき `-1`、偽のとき `0` に評価される。
よって、`MID$` 関数で取り出しを開始する位置として `2` のかわりに `2+(N<0)` を指定すると

* `N` が負であるとき、取り出しを開始する位置は `2+(-1)` すなわち `1` となり、文字列の先頭から取り出す
* `N` が負でないとき、取り出しを開始する位置は `2+(0)` すなわち `2` となり、最初の1文字を消去する

動作を実現できる。

```text
10 FOR N=-3 TO 3
20 PRINT"|";MID$(STR$(N),2+(N<0));"|"
30 NEXT N
```

![負の場合は最初の文字を消さないようにした結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99656/97a1525d-81ff-47da-bee4-76171b623bdc.png)

# まとめ

* MSX BASIC の `PRINT` 命令で非負の数値を出力すると、前後に余計な空白が出力される
* 後ろの空白の出力は、数値を文字列に変換してから出力することで回避できる
* 前の空白の位置には負の数値の出力時には符号が入るので、数値が負でない場合のみ最初の文字を除いて出力するとよい

今回は、余計な空白をそもそも出力しないようにする方法を紹介した。
しかし、例えばゲームのスコアを表示するときなど、用途によっては、1桁左から出力するなど、空白が出力されることを前提とし、それ込みで意図した表示になるよう調整するという戦略も考えられるだろう。
スクラム開発について

## 概要

スクラム開発は、アジャイル開発の手法の一つであり、短期間の作業サイクル（スプリント）を反復しながら進めるフレームワークです。ラグビーの「スクラム」に由来し、チーム全員が一丸となって開発を進めることを重視します。

## **スクラム開発の流れ**

スクラム開発は以下の手順で進行します：

1. **プロダクトバックログの作成**  
   プロジェクト目標を明確化し、必要なタスクや機能をリスト化します。

2. **スプリント計画**  
   各スプリント（通常1～4週間）の目標を設定し、実施するタスクを選定します。

3. **デイリースクラム**  
   毎日短時間のミーティングを行い、進捗状況や課題を共有します。

4. **スプリントレビュー**  
   完成した成果物をステークホルダーに公開し、フィードバックを得ます。

5. **レトロスペクティブ**  
   スプリント終了後に振り返りを行い、プロセス改善点を議論します。

## **スクラムチームの役割**

スクラム開発には以下の主要な役割があります：

- **プロダクトオーナー（PO）**  
  製品ビジョンの策定や優先順位付けを担当します。

- **スクラムマスター**  
  チーム運営や障害排除を行い、円滑なプロジェクト進行をサポートします。

- **開発チーム（エンジニア）**  
  実際の設計・開発・テストを担当するメンバーです。専門知識を活かしながら協力して作業します。

## **メリット**

1. **柔軟性**  
   仕様変更に迅速に対応可能で、市場や顧客ニーズに応じた調整が容易です。

2. **効率性向上**  
   短期間で進捗確認と調整ができるため、生産性が高まります。

3. **品質向上**  
   頻繁なフィードバックによって製品精度が向上します。

4. **顧客満足度向上**  
   開発速度と品質が高いため、顧客満足度が向上します。

## **デメリット**

1. **全体像の把握が難しい**  
   短期間で仕様変更が頻繁に行われるため、長期的なスケジュール管理が困難です。

2. **コミュニケーション依存**  
   チームメンバー間の連携が重要であり、不十分だと進捗に悪影響があります。

3. **初心者には不向き**  
   スプリント期間が短いため、経験不足のメンバーには負担が大きい場合があります。

## スクラムにおける３本の柱と５つの価値基準

スクラムにおける３本の柱と５つの価値基準は、スクラムガイドの冒頭に理論として説明がなされているものであり、スクラムを理解し実現するうえで非常に重要な部分です。

### ３本の柱
**「透明性」**
プロジェクトの進捗状況を常に可視化する。

**「検査」**
定期的な振り返りと改善を行う。

**「適応」**
変化に柔軟に対応する姿勢を持つ。

### 5つの価値基準
**「確約」**
スクラムチームは、ゴールを達成し、お互いにサポートすることを確約する。

**「集中」**
スクラムチームは、ゴールに向けて可能な限り進捗できるように、スプリントの作業に集中する。

**「公開」**
スクラムチームとステークホルダーは、作業や課題を公開する。

**「尊敬」**
スクラムチームのメンバーは、お互いに能⼒のある独⽴した個⼈として尊敬し、⼀緒に働く⼈たちからも同じように尊敬される。

**「勇気」**
スクラムチームのメンバーは、正しいことをする勇気や困難な問題に取り組む勇気を持つ。

## **まとめ**

スクラム開発は、高い柔軟性と効率性を備えたアジャイル手法であり、チーム全員が協力してプロジェクト成功に向けて取り組むフレームワークです。その一方でコミュニケーション能力や経験値が求められるため、導入時にはチーム編成や運用方法に注意する必要があります。
Google Play ConsoleのサイトURLを変更した

## 背景

Google Play Console で公開しているアプリの「デベロッパーサイトURL」を変更したくなったので、その際に必要だった手順や注意点をまとめました。  
新しいURLを Google Search Console に登録して、Google Play Console から申請、そしてメールで承認……といった一連の流れです。

自分用のメモ的な投稿ですが、同じように「サイト変えたいけど何が必要なんだろう？」という方の参考になれば幸いです。

---

## 手順

### ① Google Search Console に新しいサイトを追加

1. Google Search Console にアクセス  
2. 「プロパティを追加」→ 新しいURLを入力（例：`https://refootaskacyba.com`）  
3. DNSレコードでの所有権確認を選択し、表示された TXT レコードをドメインのDNSに追加  

    ```
    google-site-verification=XXXXXXXXXXXXXXXXXXXXXXXXXXXX
    ```

4. 自分の場合、4分ほどで所有権確認がOKになった

---

### ② Google Play Console（App Console）でのURL更新

1. [Google Play Console](https://play.google.com/console) にアクセス  
2. 対象アプリの「設定」→「デベロッパーの連絡先情報」または「アプリの詳細」から URL を更新  
3. 「サイトの所有者確認が必要です」という表示に従って、確認リクエストを送信  
4. 所有者にメールが届くので、そのメール内のリンクから承認  

---

### ③ 所有者確認時の注意点

- 確認メールを開いた後、「あなたはこのプロパティの所有者ではありません」といった表示が出た。所有者でChromeにログインしているつもりなのだが。。。
- この場合は画面の下の方にある `その他の方法` みたいなのをタップ（またはクリック）すると、なぜか承認でた。この挙動は謎のままにしておく…  

---

### ④ ついでにメールアドレスも更新

- デベロッパーの連絡先メールアドレスも、サイトに合わせて新しいアドレスに更新


---
## まとめ

Google Play Console でサイトURLを変更するには、Search Console 側で新URLの所有者であることを証明する必要がある。  
ドメイン管理に慣れていれば難しい手順ではないとおもいます。

https://refootaskacyba.com/
【ChatGPT＋4o Image Generation】の登場で、“DALL-E3が使えなくなった”と嘆くあなたに助け人をご紹介します。


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

　今回は、4o Image Generationの登場で、“DALL-E3が使えなくなった”と嘆くあなたに助け人をご紹介します。

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

　今回は、
　　4o Image Generationの登場で、
　　　“DALL-E3が使えなくなった”と
　　　　嘆くあなたに助け人を
　　　　　ご紹介します。

　昨日（2025/03/29）、
　　ChatGPTのAndroidアプリ版にも
　　　4o Image Generationが
　　　　組み込まれました。

　新しいものに触れるのは
　　うれしい反面、
　　　これまでの経験（Prompt）が
　　　　使えなくなるのは
　　　　　つらいものがありますよね。

　私も
　　それまで描いてきたキャラが
　　　同じPromptでも
　　　　出てこなくなったとき、
　　　　　ガックリしました。

　まぁ、
　　Soraが出てきて、
　　　なんとなく、Soraの画像生成が
　　　　DALL-E3に取って代わる気が
　　　　　していたので、
　　　　　　仕方ないかと
　　　　　　　諦めていましたが😭

　はい、
　　4o Image Generationは
　　　明らかにSoraの技術です。
　　　　SoraでImageを出すと
　　　　　ほぼ同じものが
　　　　　　出てきますからね。

　ともかく、
　　DALL-E3を諦めて
　　　4o Image Generationを
　　　　極めるしかないのかな、と
　　　　　思うところですが、
　　　　　　DALL-E3をそのまま
　　　　　　　使う方法があるのです。

　4o Image Generationを
　　紹介した際にも書きましたが、
　　　GPTsのDALL-Eを使えば
　　　　DALL-E3をそのまま使えます。

　まずは
　　探しましょう。

　履歴を表示して、
　　“GPTを探す”を選択。

　タグの“by ChatGPT”を選択すると
　　一番上に“DALL-E”があります。
![Screenshot_20250330-142427.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457238/abc65e60-727f-4a3a-bb89-6ccdcde3d897.png)


　こちらは
　　OpenAI公式が出しているGPTsです。
　　　GPTs発表の最初期からあります。

　使うと
　　画像が生成されます。

　もちろん、
　　DALL-E3でです。

　おそらく
　　APIを呼んで
　　　描いているのかと思います。

　これを使えば
　　DALL-E3信奉者は
　　　信者のままでいられます。

　❗注意点❗
　　ふつうに使っていれば
　　　問題はありませんが、
　　　　再生成は
　　　　　行なわないでください。

　再生成すると
　　4o Image Generationを
　　　使われてしまいます。

　これを回避するには
　　Promptの編集を選択して、
　　　そのまま送信するのです。
　　
　画像の編集機能も
　　変わらず使えます。

　そういえば、
　　4o Image Generationで描画した
　　　画像も同じように編集が
　　　　できます。

　　ただし、
　　　スマホでWeb版を使う場合は、
　　　　そのままでは
　　　　　編集画面に遷移しません。

　　ブラウザの設定で
　　　“PC版サイト”を
　　　　チェックする必要があります。

　　まぁ、小さすぎて
　　　見づらいんですけどねぇ😅

　　Androidアプリは
　　　ふつうに使えます。

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

　今回は、ここまで。
【完全版】Docker開発コンテナからGitHubへSSH接続するまでの道のり

## 🎯 はじめに

Docker開発コンテナから `git push` したら「Permission denied (publickey)」  
VSCode 上ではファイルは見えるのに、なぜか `.ssh` が使われてない…？

この記事は、そんな状況を実際に解決した一連の流れを記録した**完全なハマりポイント集＆解決まとめ**です。

---

## 📌 ゴール

- 開発コンテナから GitHub に SSH で安全に接続できるようにする
- `git pull` や `git push` をシームレスに行えるようにする
- SSH鍵を GitHub に登録し、適切にマウント＆接続確認する

---

## 🛠 環境

- ホスト：WSL2 / Linux
- コンテナ：Docker（Node.jsベース）
- GitHub：SSH接続を使用
- VSCode：DevContainer利用

---

## 1. 鍵の生成（ホスト側）

まずはホストPCで SSH鍵を作成：

```bash
ssh-keygen -t ed25519 -C "your-email@example.com"
```

プロンプトにはそのままEnterでOK（保存先は `~/.ssh/id_ed25519` ）

---

## 2. 公開鍵のGitHub登録

生成された公開鍵を確認：

```bash
cat ~/.ssh/id_ed25519.pub
```

その出力内容を GitHub の SSHキー設定に貼り付けて保存  
👉 [https://github.com/settings/keys](https://github.com/settings/keys)

---

## 3. Dockerコンテナへ鍵をマウント

```yaml
# docker-compose.dev.yml の一部
volumes:
  - ~/.ssh:/root/.ssh:ro
```

これにより、ホスト側の `.ssh` がコンテナ内の `/root/.ssh` にマウントされる。

**私はここで、マウント元を間違えていたため解決に時間がかかりました。**

(`~/`でroot直下を指定する必要があります。`app`直下ではないことを理解するまでに時間がかかりました。。)

---

## 4. パーミッション問題の対処

秘密鍵や設定ファイルのパーミッションが緩いと、SSHは読み込みを拒否します。

```bash
chmod 600 ~/.ssh/id_ed25519
chmod 600 ~/.ssh/config         # （あれば）
chmod 700 ~/.ssh                # ディレクトリ自体
```

※ VSCode上でマウント先が見えなくても、`/root/.ssh/` に鍵があればOKです。

---

## 5. SSH接続のテスト（コンテナ内）

コンテナに入って以下を実行：

```bash
ssh -T -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null git@github.com
```

### ✅ 成功すると：

```
Hi your-github-username! You've successfully authenticated, but GitHub does not provide shell access.
```

---

## 6. よくあるハマりポイントと解決

| 問題 | 原因 | 解決策 |
|------|------|--------|
| `.ssh/config` の `Bad owner or permissions` | 所有者が `root` でない or パーミッションが緩い | マウントせずコンテナ内で作成 or `chown root:root` |
| `Permission denied (publickey)` | 鍵が存在しない or 形式が壊れている | `ssh-keygen` で再生成、マウント確認 |
| `/app/.ssh` に鍵が見えない | マウント先は `/root/.ssh` | `ls /root/.ssh` で確認 |
| `libcrypto` エラー | 鍵の内容が壊れている | `ssh-keygen -y -f` で検証する or 再生成 |

---

## ✅ 最終確認：git push / pull

```bash
git remote -v
git push origin your-branch-name
```

何のエラーもなく成功すれば SSH接続＆GitHub連携は完璧です。

---

## 🎉 まとめ

- `.ssh` はホストの `~/.ssh` を `/root/.ssh` にマウントするのが正解
- `config` ファイルは便利だが必須ではない
- 所有者やパーミッションを必ずチェック
- 鍵が壊れていないか、Base64構造を見て検証できる

---

## 🙌 最後に

このプロセスを通じて「DockerとSSH、そしてGitHub」の接続を完全に理解できました。  
迷ってる人は、**まずは鍵を正しく作ってマウント先を確認する**だけでも世界が変わるはずです。
【CSS】コメントの書き方ミスに注意！CSSが反映されない時の解決方法

# はじめに
`HTML`と`CSS`でLPを制作している際に、なぜか`body`に`CSS`が反映されず、解決に時間がかかりました。本記事では、その解決方法を紹介します。

:::note warn
***この記事は<font color="Red">個人的なアウトプット</font>を目的として作成したものです。そのため、誤った情報や不足している内容が含まれている可能性があります。もし間違いや気になる点がございましたら、ぜひご指摘いただけますと幸いです***。
:::


# 事象
`body`タグに`CSS`が反映されない現象が発生しました。しかし、`header`タグには背景色が適用されていたため、`CSS`自体は正常に読み込まれていました。また、他に`CSS`の上書きが発生する要素もありませんでした。

```css
// 共通CSS

html {
  background-color: blue;
}

header {
  background-color: red;
  color: #fff;
  padding: 10px 0;
}
```

# 解決策
コメントの記述方法に誤りがありました。`JavaScript`では`//`でコメントできますが、`CSS`では`/* */`を使用します。

```CSS
/* 共通CSS */

html {
  background-color: blue;
}

header {
  background-color: red;
  color: #fff;
  padding: 10px 0;
}
```
なお、今回の問題は`body`タグ特有のものではありません。

`CSS`の記述ミスが原因であり、他のタグでも同じように影響を受ける可能性があります。例えば、`div`や`section`などのタグにも適用されないケースが発生します。


# 終わりに
最近はCSSを直接書く機会が減っていたため、初歩的なミスをしてしまいました。
【Azure】PowerShellでAzureにログインできるようにしてみた ＃初学者

PowerShellからAzureにログイン出来るようにしたのでメモとして残しておきます。

## 最新版PowerShellをダウンロード
GitHubで公開されているのでそこから最新版をダウンロードしてきます。
URLはこちら。
https://github.com/PowerShell/PowerShell/releases

{Latest}となっているものを選びましょう。
![スクリーンショット 2025-03-30 141515.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3674059/debb81e4-3a00-47dd-b1b6-b30b51076f25.png)

下にスクロールしていくとwindows 64bit版があったのでこちらをダウンロードしました。
![スクリーンショット 2025-03-30 141703.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3674059/be468c25-f6fe-4206-b2a3-890406bc5167.png)

## PowerShellからAzureにログイン
インストールしてPowerShellを立ち上げるとダウンロードしたバージョンであることが分かります。
```
PowerShell 7.5.0
PS C:\Users\user>
```

でもこのままではAzureにログインできません。
```
PS C:\Users\user> Connect-AzAccount
Connect-AzAccount: The term 'Connect-AzAccount' is not recognized as a name of a cmdlet, function, script file, or executable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
```

Azureのモジュールをインストールする必要があるようです。
```
PS C:\Users\user> install-Module -Name AZ

Untrusted repository
You are installing the modules from an untrusted repository. If you trust this repository, change its InstallationPolicy value by running the Set-PSRepository cmdlet.
Are you sure you want to install the modules from 'PSGallery'?
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help (default is "N"): A #今回は全てのモジュールをインストールするため【A】を入力。
```

モジュールのインストールが完了すればAzureにログインする準備は出来ました。
今回はDeviceCodeを使ってAzureに接続してみます。
```
PS C:\Users\user> connect-AzAccount -DeviceCode
WARNING: You may need to login again after updating "EnableLoginByWam".
Please select the account you want to login with.

[Login to Azure] To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code I8Z4LTTZ9 to authenticate.
```
PowerShell上に表示されたURLにアクセスします。
そうするとcodeを求められるので、こちらも表示されたコードを入力します。
![スクリーンショット 2025-03-30 142839.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3674059/f7cae29c-371e-489a-9f18-69a4c0f1fbad.png)

ログインアカウントを聞かれます。私は既にサインイン済みのアカウントが表示されたので、そちらを選択。
![スクリーンショット 2025-03-30 143016.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3674059/f9b4d754-40f8-4c70-90c6-c9a40439bc23.png)

【続行】を選択します。
![スクリーンショット 2025-03-30 143045.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3674059/7d5a8e8f-599b-4596-baa9-9be42f6db319.png)

これでAzureにログイン完了です。

以上。
Cloudflare D1とnext-on-pageでenv.DBを渡したいがタイプエラーになる  Drizzle hono

# はじめに

CloudflareのD1をhonoのAPIで読み取るのに時間がかかったのでまとめます

# 問題

今回next-on-pageを利用していたので`c.env.DB`からは読み込めないようなので以下のコードを書いた

https://zenn.dev/da1/articles/cloudflare-nextjs-hono-drizzle

```tsx
import { users } from "@/db/schema";
import { drizzle } from "drizzle-orm/d1";
import { Hono } from "hono";
import { handle } from "hono/vercel";

export const runtime = "edge";

declare global {
  namespace NodeJS {
    interface ProcessEnv {
      DB: D1Database;
    }
  }
}

const app = new Hono().basePath("/api");

app.get("/ping", (c) => {
  return c.text("pong");
});

app.get("/query/customers", async (c) => {
  const db = drizzle(process.env.DB);
  const result = await db.select().from(users).all();
  return c.json(result);
});

export const GET = handle(app);
```

しかしVSCodeではタイプエラーが発生

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810513/00f60765-6edb-4dc3-a9ec-7695fae92e27.png)

```
ES2015 module syntax is preferred over namespaces
```

しかたなく`env.d.ts`に移動してみましたが依然としてprocess.env.DBからエラーが出ました。

# 解決策

型を上手く合わせることで動くようになりました

```tsx
import { users } from "@/db/schema";
import { drizzle } from "drizzle-orm/d1";
import { Hono } from "hono";
import { handle } from "hono/vercel";

export const runtime = "edge";
const app = new Hono().basePath("/api");

app.get("/ping", (c) => {
  return c.text("pong");
});

app.get("/query/customers", async (c) => {
  console.log(c.env);
  const db = drizzle(process.env.DB as unknown as D1Database);
  const result = await db.select().from(users).all();
  return c.json(result);
});

export const GET = handle(app);
```

# おわりに

かなり沼ってしまったのですが一旦これでも良いのではないかと思いました。
【超基本】文字コードについて

# はじめに
人間とコンピュータでは、文字情報の扱い方に根本的な違いがあります。人間は「あ」「A」「😊」といった文字や絵文字を直接認識できますが、コンピュータはすべてのデータを数値（0と1のビット列）としてしか処理できません。このギャップを埋めるために開発されたのが「文字コード」という仕組みです。

## 人間の文字認識 と コンピュータのデータ表現
**人間の文字処理の特徴**
・視覚的な形で文字を認識
・文脈に応じて同じ形の文字でも意味を柔軟に解釈
・数千～数万種類の文字を区別して理解可能

**コンピュータのデータ処理の特徴**
・すべてのデータは0と1のビット列（2進数）で表現
・事前に定義された規則に対し厳密に従う必要がある
・メモリ効率を重視するため、できるだけ少ないビット数で表現しようとする


## 基本的な仕組み
文字コードは、コンピュータ上で文字を扱うために、文字に対して割り当てられた数値のことで、人間とコンピュータのデータ橋渡しを行なう技術のことです。
「文字 ⇔ 数値」の対応表（マッピング）として機能しています。

人間が読める文字をコンピュータが扱える数値に翻訳することを**エンコード**、その逆を**デコード**といいます。つまり、双方が理解できる形式に文字や数字を翻訳する際の対応表になっているのが文字コードです。

**エンコード**
人間が理解する文字 → 文字コードによるエンコード → コンピュータが扱える数値
※エンコードのことを「符号化」

**デコード**
コンピュータの数値 → 文字コードによるデコード → 人間が理解する文字


## 文字コードの主要構成要素
**前提：文字からバイト列への変換プロセス**

**文字からバイト列への変換は、必ずコードポイントを介した2段階のプロセスで行われます。**

文字 → コードポイント → バイト列
※基本的に、直接文字がバイト列になるわけではない。ただし、Shift-JISは直接変換される。

### 符号化文字集合
世界中の文字に「U+XXXX」形式のID（コードポイント）を割り当てられています。
これはいわば辞書のようなもので、例えば、Unicodeで「A」は「U+0041」、「あ」は「U+3042」とあらかじめ定義されています。
しかし、これはあくまでも文字とコードポイントを対応づけただけです。そこで、コードポイントをバイト列に変えるため、エンコーディングが必要になります。
これにより、同じコードポイントを使用しても、エンコーディング方式を変えるだけでバイト表現を変えることができます。

### エンコーディング方式
コードポイントを実際のバイト列に変換する方法のことです。
（例）UTF-8、UTF-16、Shift_JISなど


## 主要な文字コードの種類と特徴
**1. ASCII（アスキー）コード**
・7ビット（128文字）の文字コード
・英数字、記号、制御文字のみ
・1文字＝1バイト（実際は7ビットだが、8ビット単位で扱われる）
（例）'A' → 65 (0x41)、'0' → 48 (0x30)

**2. 拡張ASCII（ISO-8859シリーズ）**
ASCIIを8ビット（256文字）に拡張
・地域ごとに異なるバリエーション（ISO-8859-1：西欧、ISO-8859-7：ギリシャなど）
・日本語は表現できない

**3. Shift_JIS（シフトJIS）**
日本語を扱えるようにした文字コード
・ASCII互換性を維持しつつ、日本語文字を表現
・2バイト文字と1バイト文字が混在
・問題点：文字化けが発生しやすい

**4. Unicode（ユニコード）**
世界中の文字を単一の文字集合で扱うことを目的に開発
・最新版（2023年時点）で149,813文字を定義

**主要なエンコーディング方式**
・**UTF-8**：可変長（1～4バイト）、ASCII互換、Webで主流
・**UTF-16**：2バイトまたは4バイト固定、JavaやWindowsで使用
・**UTF-32**：4バイト固定、処理が単純だがメモリ効率が悪い


## 文字化けのメカニズムと防止策
**文字化けが起こる理由**
・エンコーディング方式の不一致（例：UTF-8でエンコードしたデータをShift_JISとして解釈）
・サポート外の文字を使用
・データ転送中のエラー

## 文字化け対策
・システム全体でUTF-8を使用する
・ファイルの先頭にBOM（Byte Order Mark）を付加（ただし、UTF-8では不要な場合も）
・メタデータ（HTMLのcharset、HTTPヘッダーなど）でエンコーディングを明示
・特殊文字を使用する際は文字参照（例：&#x3042;で「あ」）を利用

# まとめ
はじめのうちは、UnicodeやASCIIコードなど、言葉と定義・意味がごちゃごちゃしてしまうと思いますが、人間とコンピュータが文字をどのように表現するかを理解することで、なぜ文字化け対策などで文字コードが重要なのかが理解できると思います。
筆者もはじめ、この違いがいまいちよく理解できておらず、なぜHTMLのmeta要素でcharsetを行なうのか理解できていませんでした。
この点がクリアになると、コードの意味が理解できるようになります。

最後までお読みいただき、ありがとうございました。

## 参考URL
http://equj65.net/tech/charcode/
https://gigazine.net/news/20231005-unicode/
https://qiita.com/omiita/items/50814037af2fd8b2b21e
https://qiita.com/yuji38kwmt/items/b3a7820b4d3b544da4ff
https://www.gixo.jp/blog/12465/
https://itskillmap.com/menu2_02/
ModernBERT-base-Turkish-uncased-mlmは「İyi [MASK] sözünün üstüne gelir」の[MASK]に何を埋めてくるのか

[ModernBERT-base-Turkish-uncased-mlm](https://huggingface.co/99eren99/ModernBERT-base-Turkish-uncased-mlm)というトルコ語モデルを見つけたので、試しに使ってみた。ただ、トルコ語では「I」の小文字が「ı」なのだが、[BertNormalizer](https://huggingface.co/docs/tokenizers/api/normalizers#tokenizers.normalizers.BertNormalizer)の`lowercase=True`は「I」を「i」にしてしまうので、ちょっとだけトークナイザをいじってみることにした。Google Colaboratoryだと、こんな感じ。

```
!pip install transformers
from transformers import pipeline
from tokenizers.normalizers import Sequence,Replace,BertNormalizer
fmp=pipeline("fill-mask","99eren99/ModernBERT-base-Turkish-uncased-mlm")
fmp.tokenizer.backend_tokenizer.normalizer=Sequence([Replace("İ","i"),Replace("I","ı"),BertNormalizer(lowercase=True,strip_accents=False)])
print(fmp("İyi [MASK] sözünün üstüne gelir"))
```

私(安岡孝一)の手元では、以下の結果が得られた。

> [{'score': 0.10560256242752075, 'token': 1993, 'token_str': 'bir', 'sequence': 'iyi bir sözünün üstüne gelir'}, {'score': 0.10515685379505157, 'token': 2997, 'token_str': 'kişi', 'sequence': 'iyi kişi sözünün üstüne gelir'}, {'score': 0.03464006632566452, 'token': 2419, 'token_str': 'insan', 'sequence': 'iyi insan sözünün üstüne gelir'}, {'score': 0.03446153923869133, 'token': 6, 'token_str': '"', 'sequence': 'iyi " sözünün üstüne gelir'}, {'score': 0.03443867713212967, 'token': 2156, 'token_str': 'her', 'sequence': 'iyi her sözünün üstüne gelir'}]

「İyi [MASK] sözünün üstüne gelir」の[MASK]に「bir」「kişi」「insan」「"」「her」を埋めてきており、3番目に「insan」が来ているものの、4番目の「"」は謎である。そこそこの出来に見えるのだが、さて、トルコ語の係り受け解析に使えるかな。
急にwindows側のpythonを使おうとしてインタープリタを選択しようとしてもファイルが認識されない

表題の通り、linux側のpythonを選択しようとしてもwindows側のpythonを使おうとしてファイルが認識されないということが起こったので備忘録として記述しておく。

## 原因
結論から言うとVS codeがWindows側で動作していたから。

## 解決策
要はVS codeをlinux側で動作させばよいということになる。
1. 開きたいディレクトリに移動したらcode .で開くか
2. コマンドパレット（Ctrl+Shift+P）で「Remote-WSL: New Window」を実行し、WSL の Ubuntu 環境内で新しいウィンドウを開く。
今、「パソコン初心者」が中古Windowsパソコンを買うときに注意すべきこと

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4041503/512619c2-d1f5-482a-84fe-65cf98823416.png)
### 概要
* Windows10の無償サポートは、2025年10月14日をもって終了します。
* それ以降は Windows11 を使ったほうがよいと思われます。
    * 企業向けの有償サポートプログラムの適用を受ける場合を除く。
* ただし、Windows11 はパソコンのスペックに厳しい要求を課します。
    * そのため、__Windows10ではサポートされていたけど、Windows11では「公式にはサポートされない」パソコンがあります。__
    * 話が複雑なのは、__「Windows11では公式にはサポートされないパソコン」であっても、__ Windows11 が __現時点では「うごく」ことはある__ ということです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4041503/100541c9-f938-4cf6-8463-2e788c758ba4.png)

* この状況を利用し、 __<font color="red">「Windows11では公式にはサポートされ<INS>ない</INS>パソコン」であることには触れず（黙って）</font>、「世界的Eコマースサイト」やオークション、個人売買のサイト等で、Windows11をインストールした中古パソコンを売っている人/業者がいます(笑)__
    * なぜなら「Windows11では公式にはサポートされ<INS>ない</INS>」パソコンは、普通の企業や各種行政機関等では2025年10月15日以降、いらなくなる（使われなくなる）ことが多いので、今現在でも、安く仕入れることができるからです。
    * 「整備済み」といったいかにもちゃんとした売り文句であることが多いです。
    * 要注意キーワードは「Windows11搭載」（だれも「対応」とは言っていないw）
    * 下手をすると、ECサイト上で「ベストセラー」としてマークが付けられ、高評価を集めている場合もあります(笑)
* __<font color="red">「Windows11では公式にはサポートされ<INS>ない</INS>」</font>__ パソコンを使い続けることは、リスクがありますので、他人に迷惑をかけることも含め、自己責任(At Your Own Risk)を負える方以外はしないほうが無難だと、私は考えます。
    * 分かっている方が遊び(勉強?)で使う分には良いかと思いますが、例えばテレワークで利用され、仮に私の個人情報がそのパソコン上で扱われているようなシチュエーションを考えるとゾッとします((((；ﾟДﾟ))))ﾌﾞﾙﾌﾞﾙ

### 最低限確認すること
* Intel (インテル) の CPU であれば、Windows11 が公式にはサポートしているのは、__第8世代以降__ のCPUと、__第7世代の一部__(ノートPC用以外の、一部のハイエンドCPU)です。
* CPUだけであれば、 [Microsoft が提供するプロセッサ要件](https://learn.microsoft.com/ja-jp/windows-hardware/design/minimum/supported/windows-11-supported-intel-processors)に型番が掲載されていると安心です。
* __第4世代、第5世代、第6世代__ の Intel (インテル) の CPU は、Windows11では公式にサポートされていません。、__第7世代__ も、一部(ノートPC用以外の、一部のハイエンドCPU)を除き公式にサポートされていません。
* CPU以外にも細かな要件がありますが、パソコンの型番と「Windows11」といったキーワードで Web検索して（ググって）サポート状況を確認するか、販売者に「このパソコンは、マイクロソフトが発表しているWindows11(24H2)の最小ハードウェア要件を満たしていますか？」と聞くのもよいかもしれません。(信頼できそうな販売者であれば）

### 「Windows11では公式にはサポートされ<INS>ない</INS>」場合に何が起こるか
網羅的に挙げることは私にもできませんが、例えば、

 * ある日、Windows Update ができなくなり、セキュリティに問題がある形で使わざるを得なくなる
     * セキュリティに問題があるため、各種犯罪に巻き込まれる（被害者となる・加害者の疑いをかけられる）場合がある
 * 特定のアプリが動かない、Windows 自体が立ち上がらなくなる

などは、可能性がないとは言えないところです。

### (わかっている人向け) AllowUpgradesWithUnsupportedTPMOrCPU のリスク

CPUは自己責任ということでよいかもしれませんが、TPMは[耐タンパ](https://ja.wikipedia.org/wiki/%E8%80%90%E3%82%BF%E3%83%B3%E3%83%91%E3%83%BC%E6%80%A7%E8%83%BD)性に関わることなので、regedit するの怖くないですか？('ω')

※ 「耐タンパ性」の語感が好きなので言ってみたかっただけです(笑)
※ 「対タンパ性」ではなく「耐タンパ性」なので各種論述試験を受ける方は注意が必要です。

おしまい
Kotlinでも使えるEitherとは

# はじめに
Arrowというライブラリを導入することでKotlinでもEitherを使うことができます
### 基本的な使い方
```kotlin
// Resultのように2種類の返却物をハンドリングできる
Either<Error, String>
either {
        // ensure は条件を満たさない場合に指定した Either.Left で処理を終了する
        ensure(isSuccess) { FugaError }
         // raise は 指定した Either.Left で処理を終了する
        raise(HogeError)
        // Any.right() は Either.Right(Any) と同じ意味
        "Success!".right() 
    }

// 返却された側はfoldでクロージャーを用いて処理できる
Any.fold(
    {
    it
    },
    { error ->
    error
    }
)
```
### さいごに

Resultに慣れてる方が多いとは思いますが、Eitherを使ってみると意外と便利で読みやすいので一度試しに触ってみるのはありだと思います
git でコミット時のスクリプト実行

git でコミットが行われた際にスクリプトを実行する方法のメモ。

# やりたいこと
- git でコミットが行われた際にコミットの時刻、コミット SHA をファイルに出力し、バージョン的情報として利用

# フック
git commit を実行した際に、コミット前に実行したい処理を以下に記述しておけば、コミット前に実行してくれます。
```.git/hooks/pre-commit```

一方、git commit を実行した際に、コミット後に実行したい処理を以下に記述しておけば、コミット後に実行してくれます。
```.git/hooks/post-commit```

## pre-commit の例
コミット直前に static/pre.txt に '{日時};{ブランチ名};{コミットSHA}' を出力します。
```bash:./git/hooks/pre-commit
#!/bin/sh

OUT_FILE=static/pre.txt

DATE_TIME=$(date --utc '+%Y-%m-%dT%H:%M:%SZ')
BRANCH=$(git rev-parse --abbrev-ref HEAD)
COMMIT_SHA=$(git rev-parse HEAD)

echo -n "${DATE_TIME};${BRANCH};${COMMIT_SHA}" > ${OUT_FILE}
```
実行すると、static/pre.txt に以下のような文字列が出力されます。
```2025-03-30T03:41:32Z;test1;ceb633a8c7100c7a6c651ba08aa269aa31c90019```

## post-commit の例
コミット直後に static/post.txt に '{日時};{ブランチ名};{コミットSHA}' を出力します。
```bash:.git/hooks/post-commit
#!/bin/sh

OUT_FILE=static/post.txt

DATE_TIME=$(date --utc '+%Y-%m-%dT%H:%M:%SZ')
BRANCH=$(git rev-parse --abbrev-ref HEAD)
COMMIT_SHA=$(git rev-parse HEAD)

echo -n "${DATE_TIME};${BRANCH};${COMMIT_SHA}" > ${OUT_FILE}
```

# 実行例
README.txt を編集してコミットします。
```
git add README.txt
git commit -m "test"
```

static/pre.txt には以下が出力されています。
```text:static/pre.txt
2025-03-30T03:41:32Z;test1;ceb633a8c7100c7a6c651ba08aa269aa31c90019
```

static/post.txt には以下がされています。
```text:static/post.txt
2025-03-30T03:41:32Z;test1;ae93cd8f713c78142beeaa38c2730f3c85076c85
```

git log でコミットログを見てみると以下のようになっています。
pre.txt、post.txt にコミット前後のコミットSHAが出力されていることがわかります。
```text:
commit ae93cd8f713c78142beeaa38c2730f3c85076c85 (HEAD -> test1)
Author: ...
Date:   Sun Mar 30 12:41:32 2025 +0900

    test

commit ceb633a8c7100c7a6c651ba08aa269aa31c90019
Author: ...
Date:   Sun Mar 30 12:40:03 2025 +0900

    test
```
なお、ここでは pre.txt、post.txt は git で管理しないことを想定しています。
pre.txt はコミット前のため、コミットSHA がひとつ前のコミットで、post.txt はコミット後のため、リポジトリに反映されないためです。
アプリ開発AIエージェント　Rorkがすごい

アプリ開発AIエージェント　Rorkを使ってみました。

日々の学びを記録できる日記アプリをデモに作成してもらいました。
以下の文章をdeeplで英語訳したものをプロンプトにしました。
```
日記をつけることができるアプリ
21時に通知がきて、その日のメンタルの調子や、学びを入力する
そして、それを共有することもできる
いいねの数が多い人は週間ランキングに掲載

オレンジを基調としたUIで、日々の活動のモチベーションアップにつなげる
```
たった数分で以下のアプリが完成してしまいました。

![スクリーンショット 2025-03-30 123516.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3921190/f49a080a-0cfd-46f6-84c4-3b52570872a1.png)
QRコードから、Expo Goというアプリをダウンロードし、
もうひとつのQRコードをスマホで読み取ることで、
動作確認ができます。
![IMG_8468.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3921190/3574629c-e56c-4fe7-b47f-88027014feb1.png)
![IMG_8469.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3921190/80ca9556-7093-4944-8296-52e8e5bd8768.png)
![IMG_8470.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3921190/35751297-b208-405f-a71d-a94239ea012f.png)
![IMG_8471.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3921190/be7fc2c2-44cd-4f10-8fb4-6be960a3f0b9.png)

ある程度整ったUIのアプリが一瞬でできてしまいました。
Apple storeのテストフライト公開までやってくれるのでデプロイも楽だそうです。

コードはReactとTypeScriptを使って書かれており、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3921190/4f4f2943-929d-4bec-86ec-fa6a30797f40.png)

好みに調整することもできます。
もちろん、追加のプロンプトによるAI編集も可能です。

アイデアを形にするまでに必要なコストを削減し、アプリ開発の幅を広げることのできる、すばらしいAIエージェントだと思いました。
スマホアプリ 下調べ ざっくりと流れを理解

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680230/74ec76bb-3928-4cf5-bbb9-7c1718b5c0cb.png)


## はじめに

仕事で「スマホアプリに関わるかも」となったため、したいです。
スマホアプリは、`WebView` を使った開発にはかかわったのですが、実際に自分でアプリ部分を行うのは初めてなので、全体の流れから勉強していきたいと思います。

## ざっくりと流れ

1. 企画・設計
1. 開発環境構築
1. 開発（UI/UX、バックエンド、API連携）
1. テスト（単体テスト、ベータテスト）
1. 公開準備（ストア用ビルド、メタ情報登録）
1. テスト配信（TestFlight / Google Play Console）
1. ストア公開（審査 → 公開）
1. 運用・アップデート（分析、バグ修正、機能改善）

## 1. 企画・設計

### 目的・ターゲットの明確化

- アプリの目的（何を解決するのか？）
- ターゲットユーザー（誰が使うのか？）
- 競合分析（類似アプリとの差別化）

### 仕様策定

- 主要な機能（ログイン、決済、通知、データ保存など）
- 画面設計（ワイヤーフレーム作成）
- システム構成（バックエンドが必要か？外部APIを利用するか？）

## 2. 開発環境の準備

### Android

- 開発ツール: Android Studio
- 言語: Kotlin / Java ※今回は Fullter かな？
- SDK: Android SDK
- エミュレータ: Android Emulator

### iPhone（iOS）

- 開発ツール: Xcode（Macが必要）
- 言語: Swift / Objective-C ※今回は Fullter かな？
- SDK: iOS SDK
- エミュレータ: iOS Simulator

## 3. 開発

### フロントエンド（UI・UXの実装）

- UIデザイン（ Material Design（Android）、Human Interface Guidelines（iOS） ）
- 画面遷移の実装

### バックエンド（必要なら）

- API開発（Node.js、Spring Bootなど） ※今回は Node.js かな？
- データベース（MySQL、PostgreSQL、Firebase Firestore）
- 認証（Firebase Authentication、AWS Cognito）

### 外部サービスの組み込み

- Firebase（プッシュ通知、クラッシュレポート）
- Google / Apple 決済API
- SNS連携（Google、Facebook、LINEなど）

## 4. テスト

### 単体テスト

- ユニットテスト（JUnit、Mockito、XCTest） ※今回は Jest かな？
- UIテスト（Espresso、XCUITest） ※何が良いの？

### 結合テスト・ユーザーテスト

- 実機テスト（開発者用デバイスで動作確認）
- クラウドテスト（Firebase Test Lab、Sauce Labs）
- ベータテスト（社内テスト or 一部ユーザーによるテスト）

## 5. 公開準備

### アプリのビルド

- Android: .apk or .aab（Android App Bundle）
- iOS: .ipa（Xcodeでアーカイブ作成）

### ストア向け設定

- アイコン・スクリーンショット作成
- プライバシーポリシー、利用規約準備
- アプリ説明文（タイトル、概要、キーワード）

## 6. ストアでのテスト配信

### Android: Google Play Console

- Google Play Console に登録
- アプリをアップロード（内部テスト、クローズドテスト）
- テスターを招待し、動作確認

### iOS: TestFlight（Apple Developer）

- Apple Developer Program に登録（年額$99）
- アプリをApp Store Connectにアップロード
- TestFlightでテスターを招待し、テスト実施

## 7. アプリの公開

### Android: Google Play Store

- Google Play Consoleでアプリを「公開」申請
- 審査（通常数時間～数日）
- 承認後、ストアに公開

### iOS: App Store

- App Store Connectで「公開」申請
- Appleの審査（通常1週間前後）
- 承認後、ストアに公開

## 8. 運用・アップデート

### 分析・改善

- Firebase Analytics / Google Analyticsでユーザー行動を分析
- クラッシュレポート（Sentry、Firebase Crashlytics）

### アップデート

- バグ修正・機能追加
- ストアのポリシー変更対応
- 定期的なOSアップデート対応


## 補足

### 企業アプリの場合: MDM（モバイルデバイス管理）を利用

Mobile Device Management（モバイルデバイス管理） の略称であり、企業・組織が所有するモバイルデバイスやPC、タブレットを一元管理するための仕組みやソリューション

### PWA（Progressive Web App）という選択肢もある（ストア申請不要）

PWA（Progressive Web Apps）は、Webアプリにネイティブアプリのような機能を提供し、ユーザー体験を飛躍的に向上させる技術です。プッシュ通知などを活用することで、顧客エンゲージメントを深め、マーケティング効果を最大化します

## おわりに

開発の部分は問題なさそうですが、実機テスト～リリースまではもっと勉強が必要ですね。
特に申請系は、やってみないとわからない事が多々あると思うので、みんなに相談しながらやってみます！

今後、リリース部分も事前に調査して記事にしたいと思います。

---

**参考（感謝）**

- [アプリ公開の流れ｜アプリ開発からリリース・運用までにするべきこと](https://youtu.be/s8-4peFX8sM?si=kw1kd6-3QKVWaeLA)
- [PC自作から始めるスマホアプリ開発 #41 アプリリリース編 アプリストアへ提出する](https://youtu.be/kutAcBOlIwI?si=9tmys-K5_KUo3pcl)
- [PWA（Progressive Web Apps）とは？どう凄いのか、導入するメリットは](https://www.profuture.co.jp/mk/column/what-is-progressive-web-apps)
🚀 Laravelで最小のECサイトをDDDで作る！（マイグレーション編）


こんにちは！Laravel×DDDシリーズ第6弾です😊 これまでドメイン設計を進めてきましたが、いよいよ実際にLaravelのプロジェクトを作成して、データベースの構造を整備していきましょう。

マイグレーションを使うことで、データベースをコードベースで管理できます。これでDDDの設計が実際のDB構造と一致しますよ✨

## 📌 マイグレーションファイルの構成

今回作成するマイグレーションファイルは以下の通りです。

- ユーザー(users)
- 商品(products)
- カート(carts)
- 注文(orders)

### ① ユーザーテーブルのマイグレーション

ユーザー情報を管理します。

```php
public function up(): void
{
    Schema::create('users', function (Blueprint $table) {
        $table->id();
        $table->string('name');
        $table->string('email')->unique();
        $table->string('password');
        $table->timestamps();
    });
}
```

### ② 商品テーブルのマイグレーション

商品情報を管理します。

```php
public function up(): void
{
    Schema::create('products', function (Blueprint $table) {
        $table->id();
        $table->string('name');
        $table->integer('price');
        $table->integer('stock');
        $table->timestamps();
    });
}
```

### ③ カートテーブルのマイグレーション

ユーザーごとのカートを管理します。カート内の商品情報はJSON形式で管理します。

```php
public function up(): void
{
    Schema::create('carts', function (Blueprint $table) {
        $table->id();
        $table->unsignedBigInteger('user_id')->unique();
        $table->json('items');
        $table->timestamps();

        $table->foreign('user_id')->references('id')->on('users')->cascadeOnDelete();
    });
}
```

### ④ 注文テーブルのマイグレーション

注文情報と注文された商品内容をJSON形式で管理します。

```php
public function up(): void
{
    Schema::create('orders', function (Blueprint $table) {
        $table->id();
        $table->unsignedBigInteger('user_id');
        $table->string('status')->default('pending');
        $table->json('items');
        $table->timestamps();

        $table->foreign('user_id')->references('id')->on('users')->cascadeOnDelete();
    });
}
```

## 📖 マイグレーションの実行方法

マイグレーションファイルを作成したら、以下のコマンドで実際にDBへ反映しましょう。

```bash
php artisan migrate
```

これで、設計したドメインとデータベースの構造が完全に一致するようになります！

## 🎯 マイグレーションを使うメリット

- データベース構造が明確で再現性が高まる
- ドメイン設計に忠実なDB構造になる
- 変更管理が簡単になり、チーム内で共有しやすくなる

これでDDD設計から実際の実装への準備が整いましたね！次回は具体的なリポジトリの実装を進めていきましょう✨😊
ちいぽけのaとかの考察

<!-- ちいぽけのaとかの考察 -->

## はじめに

『ちいかわぽけっと』というゲームが先日配信された。

蓋を開けてみたら討伐を放置することがメインのゲームだったわけだが、パラメータの表示などに違和感があった。

数字の後ろに「a」などのアルファベットがついている。

ゲームを進めていくと、このアルファベットはどんどん進んでいった(この記事を書いている時点では``f``まで確認した)。

今回はこのアルファベットについて調べてみることにした。

## 挙動の調査

とりあえず数字の表示について調べてみた。

記事を書いている今もちいぽけを放置しているので、画面に表示されている数値を列挙してみる。

- 107e
- 79.4d
- 4.13e

なるほど、おそらくは有効数字三桁+アルファベットという形式で表示されているようだ。

つまり、ちいぽけの数値表示は以下のような表現を取ることができると思われる。

```
A[a-z]
```

ここで、``A``は有効数字三桁の数値、``a-z``はアルファベットの小文字を表す。

また、``A``については$1 \leqq A < 1000$が成り立っている。

これらの事実から、アルファベットが切り替わるタイミングで、数値部分が$1/1000$されることが分かる。

つまり、実際の数値は有効数字部分に$10^3$をアルファベットの分掛けたものになるというわけである。

## 変換プログラム

簡単だが、ちいぽけ表記を実際の数値にするには以下のようなプログラムを組めばよい。例としてPythonの関数として実装してみた。

```python
def convert_chipoke_number(chipoke_number: str):
    if 'a' <= chipoke_number[-1] <= 'z':
        # 末尾がアルファベットならその部分を取得
        alpha = chipoke_number[-1]
    else:
        # 末尾がアルファベットでなければそのまま返す
        return chipoke_number
    # 数字の部分を取得
    number = chipoke_number[:-1]
    # アルファベットの数値を計算
    alpha_value = ord(alpha) - ord('a') + 1
    # 実際の数値を計算
    actual_value = int(float(number) * (10 ** (3 * alpha_value)))
    return actual_value
```

コメントにある通り、``ord``関数を使ってアルファベットの順番を取得し、実際の値の計算に利用したものである。

以下のリポジトリに使用できる状態で置いておく。

https://github.com/Gitudon/Test-Repositories/tree/master/Chipoke-Converter

## 考察

ちいぽけ表記では、数値が大きくなるにつれてアルファベットが進んでいくだろう。しかし、アルファベットは26文字しかないわけで、このままだと``999z``でカンストしてしまうだろう。

似たようなゲームでは``ab, ac, ...``と続くようなので、おそらくこのような形式になると思われる。

ただ、少しTwitterで調べた限り``z``まで到達している人は見当たらなかった。``z``の次が``ab``となるかについての真偽は調査中である。

とりあえずアルファベットの仕組みは分かったのだが、なぜこのような形式なのだろうか、そこを少し考察してみる。

以前『カイジ 闇の黙示録』というゲームをやったが、そのゲームは稼いだ金額を通常の10進数で表示していた。

そのため、``int``型の最大値すなわち$2^{31}-1$(約21億)。までしかお金が稼げなかった。24億脱出編の再現が不可能である。

他のゲームでもカンストといえば$2^{31}-1$が多いと聞いたことがある。

ちいぽけで採用された「アルファベットを使う」という形式は、このようなカンストを回避することに有用だと考える。仮に``z``までしかなかったとしても、これは$999\times (10^3)^{26}$までの数字を表現できる。おおよそ$10^{81}$であり、無量大数よりも巨大である。『ガンダムトライブ』も真っ青の数値だ。

以上のことから、ちいぽけで採用されているこの記法は、巨大な数を扱いやすくするための工夫であると考えられる。
AWS認定クラウドプラクティショナー 改訂第三版

『AWS認定クラウドプラクティショナー 改訂第三版』を購入しました。AWSの基礎概念、IAMによるアクセス管理、VPCを使ったネットワーク構成、EC2やS3など主要サービスの仕組みを体系的に学べます。特に、Well-Architected Frameworkや責任共有モデルについての解説が実践的で理解が深まりました。料金モデルやコスト最適化のポイントも具体的に書かれており、試験対策だけでなく業務にも活かせる内容です。AWS初心者や資格取得を目指す方に最適な一冊です。
JavaScriptのthisバインディングを設計で制す：暗黙・明示・アロー関数の本質と選定戦略

## 概要

JavaScriptにおける `this` の挙動は、**実行時の呼び出し方によって決まる**という点で、他言語とは一線を画す。  
つまり `this` は、**定義ではなく呼び出しによって決定される**。

以下のような状況において、`this` の設計がバグの温床になる：

- コールバックで `this` が失われる
- メソッドの `this` が意図しないオブジェクトになる
- `bind()` を忘れて関数が壊れる
- アロー関数と通常関数が混在して挙動が読めない

この記事では、`this` の挙動を完全に制御するために、**暗黙的・明示的・アロー関数の使い分け戦略**を提示する。

---

## thisの決定ルール

```text
① new キーワードが使われている？ → thisは新しいインスタンス
② 明示的に bind/call/apply？ → thisは指定された値
③ オブジェクトからの呼び出し？ → thisはそのオブジェクト
④ アロー関数？ → 外側のthisを継承
⑤ 上記いずれもなし → thisはグローバル（strictなら undefined）
```

---

## 1. 暗黙的バインディング（呼び出し元に依存）

```js
const user = {
  name: 'Toto',
  greet() {
    return `Hello, ${this.name}`;
  }
};

user.greet(); // Hello, Toto
```

→ `this` は `user` にバインドされる

---

### ❌ 呼び出し方が変わると `this` が消える

```js
const fn = user.greet;
fn(); // ❌ undefined（または global の name）
```

---

## 2. 明示的バインディング：bind / call / apply

```js
function greet() {
  return `Hello, ${this.name}`;
}

const user = { name: 'Toto' };

greet.call(user);  // Hello, Toto
greet.apply(user); // Hello, Toto

const bound = greet.bind(user);
bound();           // Hello, Toto
```

### ✅ 使い分け

| メソッド | 引数の渡し方             | 実行タイミング |
|----------|--------------------------|----------------|
| `call`   | 値をカンマで並べて渡す   | 即時           |
| `apply`  | 引数を配列で渡す         | 即時           |
| `bind`   | 引数を保存して返す関数   | 遅延（再実行） |

---

## 3. アロー関数によるバインディングの固定

```js
const obj = {
  name: 'Toto',
  greet: () => {
    console.log(this.name);
  }
};

obj.greet(); // ❌ undefined（thisはグローバル）

// 正しい使い方
class Button {
  constructor(label) {
    this.label = label;
    this.onClick = () => {
      console.log(this.label); // ✅ 常にインスタンスのthis
    };
  }
}
```

→ アロー関数は `this` を**定義時に外側から自動的に継承**する

---

## this に関する典型的なバグ例

### ❌ setTimeoutで this が失われる

```js
function Timer() {
  this.seconds = 0;
  setInterval(function () {
    this.seconds++; // ❌ this はグローバル
  }, 1000);
}
```

→ ✅ 解決策：アロー関数 or bind

```js
setInterval(() => this.seconds++, 1000);
```

---

## 設計で選ぶ this バインディング戦略

| シーン                         | 推奨構文           | 理由 |
|--------------------------------|--------------------|------|
| コールバックでthis保持         | アロー関数         | スコープ継承で安全 |
| メソッド定義                  | 通常関数（宣言/式）| 呼び出し元バインド |
| 再利用可能な関数              | bind               | 明示的にバインド |
| setTimeout / setInterval での this | アロー関数 or bind | 暗黙バインディングは破綻する |

---

## thisを完全に理解する一問一答

```js
const obj = {
  val: 42,
  method() {
    return this.val;
  }
};

const f = obj.method;
f();             // ❌ undefined
obj.method();    // ✅ 42
f.call(obj);     // ✅ 42
const b = obj.method.bind(obj);
b();             // ✅ 42
```

---

## 結語

JavaScriptの `this` は「文法的に定まるもの」ではなく、「**設計的に定義するもの**」である。

- `function` か `=>` かではなく、“**どこで実行されるか**”が重要
- `this` を失わない設計をすることは、“**コードの一貫性**”を保証するということ
- 明示（bind）・継承（arrow）・委譲（call/apply）を**意図的に選び分ける**ことが重要

**「なぜ this をこう扱ったのか」を説明できる設計者が、JavaScriptを制する。**
関数定義3形態を設計で使い分ける：function宣言 / 関数式 / アロー関数の違いと戦略的活用

## 概要

JavaScriptでは、関数を定義する方法が複数存在する：

- `function` 宣言（Function Declaration）
- 関数式（Function Expression）
- アロー関数（Arrow Function）

一見どれも「関数を作るだけ」のように見えるが、  
実際には **スコープ、this、巻き上げ、再定義可能性** など、明確に異なる仕様を持っており、**設計目的に応じて選ぶ必要がある構文**である。

---

## 1. `function` 宣言

```js
function greet(name) {
  return `Hello, ${name}`;
}
```

### ✅ 特徴：

- **巻き上げ（hoisting）される** → 定義より前でも使用可
- 名前がスコープに登録される
- 再定義しやすい（特にグローバルでは注意）

---

## 2. 関数式（Function Expression）

```js
const greet = function(name) {
  return `Hello, ${name}`;
};
```

### ✅ 特徴：

- **式の一部として関数を定義**する
- 巻き上げされない
- const/let と組み合わせることで**再代入を防げる**
- 即時実行関数（IIFE）にも使われる

---

## 3. アロー関数（Arrow Function）

```js
const greet = (name) => `Hello, ${name}`;
```

### ✅ 特徴：

- `this` を**自動的に外側から継承**
- **bind不要**、コールバックやクロージャとの相性が良い
- コンストラクタとしては使えない（`new`不可）
- `arguments` オブジェクトを持たない

---

## 構文的・設計的な違い比較

| 項目                   | 宣言関数       | 関数式           | アロー関数         |
|------------------------|----------------|------------------|--------------------|
| 巻き上げ               | ✅ あり         | ❌ なし           | ❌ なし             |
| `this` の挙動          | 呼び出し元に依存 | 呼び出し元に依存 | 外側の `this` を継承 |
| コンストラクタ使用      | ✅ 可能         | ✅ 可能           | ❌ 不可             |
| `arguments` 利用       | ✅ 使用可       | ✅ 使用可         | ❌ 不可             |
| 構文の簡潔さ           | 通常           | 中間             | ✅ 最短             |
| 再代入の防止（const）   | ❌ 不可         | ✅ 可             | ✅ 可               |

---

## 使用判断フロー

```text
① 関数を再利用 or 上位スコープから呼び出す？ → function 宣言

② 再代入不可 & this が必要？ → 関数式 + const

③ this を明示的に制御したい？ → アロー関数

④ コンストラクタ関数として使用？ → function 宣言 or 関数式

⑤ コールバック処理？ → アロー関数が最適
```

---

## 実務ユースケース

### ✅ this を明示的に固定したい場合（アロー関数）

```js
class Button {
  constructor(label) {
    this.label = label;
    document.addEventListener('click', () => {
      console.log(this.label); // ✅ 外の this を参照
    });
  }
}
```

---

### ✅ 巻き上げを活用する（宣言関数）

```js
// 呼び出しが先でもOK
greet('Toto');

function greet(name) {
  console.log(`Hi, ${name}`);
}
```

---

### ✅ IIFE（即時実行関数）によるスコープ分離（関数式）

```js
(function() {
  const secret = 'hidden';
  console.log(secret);
})();
```

---

## よくある落とし穴

### ❌ アロー関数はメソッド定義に向かない

```js
const obj = {
  name: 'Toto',
  greet: () => {
    console.log(this.name); // ❌ undefined
  }
};
```

→ ✅ 通常の関数式または宣言関数を使うべき

---

### ❌ 関数宣言の再定義によるバグ

```js
function log() { console.log('A'); }
function log() { console.log('B'); } // 上書きされる

log(); // 'B'
```

→ ✅ const + 関数式で防げる

---

## 結語

関数の定義方法は、**単なる書き方の違いではない。**  
それは **責務・スコープ・バインディング・挙動** を設計する構文的選択である。

- 再利用性と可読性 → `function` 宣言
- スコープ限定と制御性 → 関数式 + const
- コールバックとクロージャ → アロー関数

構文を選ぶとは、「どのような関数を設計したいか」を定義すること。  
**“何を書くか” より “なぜその書き方にしたのか”** を常に意識することが、プロフェッショナルな設計の第一歩である。
Promise / async-await / Generatorの違いと使い分け：JavaScript非同期設計のための構文戦略

## 概要

JavaScriptにおける非同期処理には、以下の3つの主要な構文スタイルが存在する：

- `Promise`: 非同期処理の構造化
- `async/await`: 同期風の記述で非同期処理を簡潔に
- `Generator`: 処理の“中断と再開”を可能にするイテレーター

それぞれが持つ特性と設計思想は異なり、  
「どの構文を使うか」は単なる好みではなく、**制御フローの設計選択**そのものである。

---

## 対象環境

```text
JavaScript（ES6〜ES2023）  
Node.js / モダンブラウザ両対応
```

---

## 1. Promise：非同期処理の構造化と連結

```js
function fetchData() {
  return new Promise((resolve, reject) => {
    setTimeout(() => resolve('data'), 1000);
  });
}

fetchData()
  .then(result => console.log(result))
  .catch(err => console.error(err));
```

### ✅ 特徴

- `then()` / `catch()` / `finally()` によるチェーン処理
- 並列実行 (`Promise.all`) に強い
- 可読性は低くなりがち（ネストで複雑化）

---

## 2. async/await：同期処理のように非同期を書く

```js
async function load() {
  try {
    const data = await fetchData();
    console.log(data);
  } catch (e) {
    console.error(e);
  }
}
```

### ✅ 特徴

- ✅ 見た目が同期的 → 可読性が高い
- ✅ エラーハンドリングも `try/catch` で統一
- ❌ 並列処理は `await` の順番に依存する → `Promise.all()`との併用が必要

---

### 並列実行したい場合

```js
const [a, b] = await Promise.all([fetchA(), fetchB()]);
```

---

## 3. Generator（+ coライブラリなど）

```js
function* task() {
  yield new Promise(resolve => setTimeout(() => resolve('step1'), 500));
  yield new Promise(resolve => setTimeout(() => resolve('step2'), 500));
}
```

- `yield` によって処理を一時停止できる
- `for...of` や `next()` により段階的に処理を進行
- 単体では非同期制御は難しく、`co` や `redux-saga` などの中間層と併用

---

### async generator + `for await...of`

```js
async function* steps() {
  yield await fetch('...');
  yield await fetch('...');
}

for await (const res of steps()) {
  console.log(await res.json());
}
```

---

## 構文・設計の違いまとめ

| 項目                  | Promise         | async/await           | Generator              |
|-----------------------|------------------|------------------------|------------------------|
| 見た目の構造           | チェーン構造     | 同期的構造             | 明示的なステップ制御   |
| 非同期サポート        | ✅               | ✅（awaitで内部的にPromise） | ❌（明示的にPromiseをyield） |
| 並列処理の簡便性      | ✅               | ⚠️ 要 `Promise.all()`   | ❌ やや難解             |
| 制御の細かさ           | 中程度            | シンプル               | 高い（中断・再開）      |
| ライブラリ併用の必要性 | なし             | なし                   | 必要（co / redux-saga）|

---

## 実務での設計判断フロー

```text
① 非同期処理が1回だけ？ → async/await

② エラーをtry/catchで管理したい？ → async/await

③ 複数Promiseを並列に処理したい？ → Promise.all + async/await

④ 制御フローを段階的に記述したい？ → Generator + ライブラリ

⑤ 同期・非同期の“混在”処理？ → Generatorが最適
```

---

## よくあるミス

### ❌ async関数は Promise を返すことを忘れる

```js
async function example() {
  return 42;
}
example().then(v => console.log(v)); // 42（Promiseで返ってくる）
```

---

### ❌ await の使いすぎによる逐次化

```js
// ❌ 順番に実行されて非効率
const a = await fetchA();
const b = await fetchB();

// ✅ 並列化
const [a, b] = await Promise.all([fetchA(), fetchB()]);
```

---

## 結語

非同期制御構文は、ただの書き方ではない。  
**制御の明確さ、エラー処理の一貫性、並列性、再利用性**――  
それらを設計としてどう選び、組み立てるかが問われている。

- `Promise` は構造化の基盤  
- `async/await` は可読性の王者  
- `Generator` は制御性の鬼神

構文を知るだけでは設計にはならない。  
**“選ぶ理由”を理解し、“捨てる理由”を持てることが、設計者の第一歩である。**