OmniAICreator/Qiita-1.07M huggingface dataset:
Tailscaleで遠隔から自宅PCを触れるようにした話

# はじめに
自宅のPCの自宅外から操作したいと思った初心者がTailscaleを使ってみただけです

# やりたかったこと
下図のような感じで自宅PCに踏み台用VMを作って遠隔から自宅NWの端末に触りたい
踏み台VM：ubuntu-server24.01

![NW構成図_202506.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2663827/ea0b859b-6eba-4c07-b371-9358049a6a1d.png)

# 案
遠隔からの通信なのでVPNを使ってセキュリティ意識してやってみたかった
そこで2案考えた
案1. 自前でVPNサーバを立てる
案2. Tailscaleなどのプラットフォームを用意しているものを利用する

# 案1 自前でVPNサーバを立てる
結論から言うと無理だった。
正確には、自宅の環境では無理だった

## 考えていた方針
VMと遠隔端末側にwireguardを入れて鍵のやりとりやIFの設定を行い通信させようとしていた。
感覚的にはこんな感じ
![自宅NW_パケット.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2663827/fa2a9f0b-2be7-426c-a2be-578d8b2824f9.png)

特定ポート番号でポート転送させるイメージだった
ルータ側には遠隔端末しかポート転送させないようなセキュリティの問題もあった。
正直、危険なことしていると感じていた。。。。

## 結果
ポート転送云々の話の前に、自宅のネット環境がマンションタイプなのもあって自宅NWのインターネット側IPにパケットを送れなかった。
### 試したこと
- 試しに遠隔端末を自宅NW内に入った状態でVPNを作って接続
   -> うまく接続できた
- 携帯のテザリングで遠隔端末をネット接続した状態でVPN接続
  ->  うまくできず。踏み台VM側のキャプチャでもwireguardパケットが届いていない

## 考察
多分、自宅NW内のルータの一段上に集約しているルータ(?)があって、そこからIPとかも払い出されているのかなと勝手に推測
集約しているルータに手を出すわけにはいかない（手を出せない）、ので案1は失敗

# 案2 Tailscaleなどのプラットフォームを用意しているものを利用する
結論としてはうまくいった
めっちゃ簡単だった

Tailscaleの公式サイトに載っている手順通りに行ったらうまくいった。
## 簡単な手順
- Tailscale内でアカウントを作成
- 踏み台VMと遠隔端末側にTailscaleを入れて、表示されたURLからログインする
- 踏み台VMと遠隔端末のVPN用IPが払い出されるので、接続する時にはTailscaleを有効にしてsshするだけ

## 考察
Tailscale自体はwireguardが行なっている鍵認証や一時鍵の生成を代わりに行う中継サーバを用意している感じかと想定している。
 -> 自宅PC側のパケットキャプチャをしてみると鍵の初期化やレスポンスのパケットが飛んでいなかったため

# まとめ
Tailscaleの登録自体はすぐに終わったので案1でかけた時間はなんだったのかと思っていたが、VMを作る練習やufw、EDRのfalcoを入れてみるきっかけになったので結果的には糧になった。

# wireguardのパケットキャプチャを取ってみたので見てみた
案1で行ったキャプチャからの抜粋
handshakeとresponseを大体120秒間隔で行なっているように見える
一時鍵をサーバとクライアント側で作成し、対向側の公開鍵で暗号化する感じなのk

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2663827/f2ed1781-c87b-4ed6-9907-1695a2906d7d.png)
縦に広いモニターはコーディングに最適だった。RD280Uレビュー

## はじめに

こちらの記事は、[【Qiitaユーザー限定】BenQプログラミングモニターレビュワー募集キャンペーン](https://qiita.com/official-columns/topics/202505-benq-review/)で、ベンキュージャパン株式会社からモニターのプレゼントを受けて、作成しました。


普段から開発業務をしていると、「あと10行上までコードが見えていたら」「ターミナルとエディタを並べても窮屈じゃなければ」といった場面が何度もあります。特に縦方向の情報量は、意外と作業効率に直結します。

今回レビューする **BenQ RD280U** は、縦に広いアスペクト比（3840×2560）を持ち、4K+の高精細表示が可能なプログラミング特化モニターです。

実際に数日間使用してみたところ、「コーディングに最適」という言葉は決して誇張ではなく、視界の広がりや疲労感の軽減、設定の柔軟性など、随所に“開発者向け”の工夫が感じられました。

この記事では、RD280Uの実際の使用感と機能面、そしてデスク環境との相性について、写真を交えて詳しく紹介していきます。

---

## 設置後のデスク環境

まずは、RD280Uを設置した直後の状態がこちらです。

![RD280U設置直後のデスク](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3303371/a4da74fa-39d3-4585-af78-5dac03849aff.jpeg)

*写真1：RD280U（左）を設置した直後のデスク。マットな反射軽減パネルが落ち着いた印象を与える。*

---

## コーディング用途での使用感

RD280Uは、3840×2560の高解像度と縦に広い表示領域により、エディタの行数を多く表示でき、コード全体の見通しが格段に向上しました。

![VSCodeでの作業画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3303371/5eed16a7-4b55-4da9-8b9e-a02d884b83a7.png)

*写真2：cursorを使用中の画面。シンタックスハイライトもくっきり見える。*

特にコーディングモード（ダークテーマ）との相性が非常に良く、明暗のコントラストがしっかりしていて、ハイライトの視認性も抜群です。反射も少なく、目の疲労感を感じにくくなりました。

---

## USB Type-Cの便利さ

USB Type-C 1本で給電・映像出力・デバイス接続が可能なため、ノートPCとの接続が非常にスムーズです。ケーブルの取り回しが最小限で済み、デスク周りがすっきり整いました。

---

## Display Pilot 2による柔軟な設定と同期

BenQが提供する専用アプリ「Display Pilot 2」では、モード切替や画面分割などの設定が直感的に操作できます。  
さらにアカウント連携により、**社用PCと趣味用PCで設定を使いまわせる**のも大きな魅力です。

![Display Pilot 2のUI画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3303371/e74c4929-881c-45c2-a53e-5cd75cba93e8.png)

*写真3：「Display Pilot 2」アプリ画面。モード切替やブルーライト軽減、色補正機能など多彩なオプションが用意されている。*

設定を一元管理できるため、使用環境を問わずに同じ作業体験を得ることができます。

---

## まとめ

RD280Uは、以下のようなニーズを持つ開発者にとって非常に魅力的な選択肢です：

- コードを縦に長く見たい
- 目に優しく、反射を抑えたい
- USB-Cでケーブルを減らしたい
- モニター設定を複数環境で統一したい

特に作業に没頭できる「視認性の良さ」と、Display Pilot 2 による柔軟なカスタマイズ性は大きな価値があります。  
今後も継続してメインモニターとして使用していく予定です。

## 余談：旧モニターはどうなった？

ちなみに、元々使っていたモニターは**RD280Uの右側に縦置き**して、現在も活用中です。

![旧モニターを縦置きにした様子](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3303371/a4da74fa-39d3-4585-af78-5dac03849aff.jpeg)
*写真4：RD280U（左）と縦置きの旧モニター（右）。黒を基調としたデスク環境が落ち着いた印象。*

主に**ネットサーフィンや資料閲覧、Slackの常時表示**などに使っていて、サブモニターとしての役割を担ってくれています。  
コーディング用の広くて高精細なメインディスプレイと、軽作業用のサブモニターという分担が明確になり、作業効率も一段と向上しました。
PHPのデバッグ環境構築の備忘録（Xdebugの設定）①


この記事は、「独学エンジニア」という学習サイトで学んだ内容を、将来自分で見直すために記録している備忘録です。

Xdebugの設定とVS Codeでのデバッグ機能を有効にするまでの手順を簡潔にまとめます。



https://dokugaku-engineer.com/course/serverside


---

## 検証環境

- PHP: 8.4.6
- Xdebug: 3.4.2
- Docker: 27.2.0
- Docker Compose: 2.29.2
- VS Code: 1.101.0
- Dev Containers: 0.417.0
---

### 1. **VS Codeのリモート開発拡張機能のインストール**

- **手順**:
    - VS Codeの左側の「拡張機能」アイコンをクリック。
    - `Dev Containers`と検索し、該当する拡張機能をインストール。
補足: 以前の名称は Remote - Containers でしたが、現在は Dev Containers に変更されています。 
- **確認**: 左下にリモート接続用のアイコンが表示される。

---

### 2. **リモート開発環境の設定**

- **設定ファイル**: `devcontainer.json`
- **主な設定項目**:
    - **name**: 開発環境の名前（例: `Part3`）。
    - **dockerComposeFile**: Docker Composeファイルのパス。
    - **service**: デバッグ対象のコンテナ名（例: `app_container`）。
    - **workspaceFolder**: 作業フォルダパス（例: `/var/www/html`）。
    - **forwardPorts**: ホストとコンテナ間で転送するポート（例: `9003` for Xdebug）。
    - **extensions**: リモート環境で使用する拡張機能を指定（例: PHP Debug, IntelliSenseなど）。

---

### 3. **Xdebugの設定**

- **DockerfileでXdebugをインストール**:
    
    ```
    RUN pecl install xdebug \
        && docker-php-ext-enable xdebug
    
    ```
    
- **Xdebug設定ファイル**: `xdebug.ini`や`php.ini`の一部。
    
    ```
    xdebug.mode=debug
    xdebug.start_with_request=yes
    xdebug.client_host=host.docker.internal
    xdebug.client_port=9003
    xdebug.log=/tmp/xdebug.log
    
    ```
    
- **コンテナ内の設定反映**: `php.ini`やXdebugの設定が正しいことを確認。

---

### 4. **VS Codeのデバッグ設定**

- **設定ファイル**: `.vscode/launch.json`
- **主な設定項目**:
    
    ```json
    {
      "version": "0.2.0",
      "configurations": [
        {
          "type": "php",
          "request": "launch",
          "name": "Listen for XDebug",
          "port": 9003
        }
      ]
    }
    
    ```
    
- **デバッグツールバー**: 左側の「虫」アイコンをクリックし、適切な設定が選択されていることを確認。

---

### 5. **リモートコンテナに接続**

- **手順**:
    - 左下のリモート接続アイコンをクリック。
    - 「Reopen in Container」または「Open Folder in Container」を選択。
    - 必要なフォルダを選び、接続を待つ。

---

### 6. **デバッグの実行**

- **確認**:
    - ブラウザやクライアントからリクエストを送信。
    - VS Codeの「虫」アイコンをクリックしてデバッグセッションを開始。
    - ブレークポイントが正しく動作するか確認。

---

### トラブルシューティング

- **設定の見直しポイント**:
    - `devcontainer.json`のパスやポート設定。
    - DockerfileでのXdebugインストールと設定。
    - `launch.json`のポート番号（Xdebugと一致しているか）。
    - ブラウザやクライアントがXdebugをトリガーしているか確認。

---
以上が、自分用の備忘録として、今後デバッグ環境を再構築する際の参考にできるよう整理した内容になります。
これからも開発効率を高めるために、XdebugとVS Codeの活用していきたいと思います。
Github Copilot Coding AgentでIssueをCopilotに任せると感動した話

## はじめに

普段個人的にアプリを作って遊んでいるのですが、今まではGithub Copilotを使ってコード補完だったり、ChatGPTに質問してコード書いてもらったりして、実装してました。

しかし、なんとなくあまり私のやりたいことが正確に伝わらない...
（プロンプトの勉強も足りてませんが）

できるだけAIに任せるタスクを細分化しなければならず、ちょっとめんどいなと思ってきました（AIが出たての頃はこれでも感動してたのにね...）

今のAIコーディングならもっとすごいことができるだろ！とは薄々知ってたのでちょっと探してみました

## Copilot Coding agentという選択肢
やはり、Githubを普段から使ってる身からするとGithubでなんとかできるやろ！と思って調べました。

なんと、GithubのCoding agentを使うとIssueをCopilotに任せると、自動でプルリク作って修正もしてくれると！

これだとPRのコメントで修正依頼もCopilotに出せるので、私がやるのは動作確認とソースのレビューのみじゃんとなり使ってみようと思いました。

ただ、この機能使うにはGithub Copilot Pro+に登録する必要があります。
Github Copilot Pro+は通常のGithub Copilot Proが月10ドル、年100ドルに対し月39ドル、年390ドルと４倍近い値段です。

https://docs.github.com/ja/copilot/about-github-copilot/plans-for-github-copilot

## 実際に使ってみた
実際に使ってみようと思い、公式のドキュメントを見てみました

https://docs.github.com/en/enterprise-cloud@latest/copilot/using-github-copilot/coding-agent/about-assigning-tasks-to-copilot

### 導入
導入するために設定のGitHub Copilotからプランをアップグレードします。
アップグレードすると設定メニューのCopilotにCoding agentの項目が追加されます。
（この項目、私は追加されるまでPro+にアップグレードしてかr数時間かかりました）
![スクリーンショット 2025-06-18 21.51.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3367262/31acff4b-5524-43ec-8098-10f12f030b52.png)

次は、Coding agentを押下して、Coding agentを使うリポジトリを指定します
（今回は、全てのリポジトリでアクセス可能にしてます）
![スクリーンショット 2025-06-18 21.56.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3367262/8508075f-0161-4667-ab1d-03bee0115643.png)

### 実際にIssueを立てる
実際に対象のリポジトリでissueを立ててアサインをCopilotにします。
![スクリーンショット 2025-06-18 22.02.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3367262/df885704-b8fc-4f69-b18a-5552bc352c12.png)

そして、Issueを作成します。すると自動で、プルリクを作成してくれ、そのプルリクが完了するとレビュー依頼が飛んできます。
![スクリーンショット 2025-06-18 22.02.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3367262/07905f57-d6ae-47a7-8d21-d1ea41f1e09a.png)

### 修正させる
意図したソースではなかった時は下記のようにして`@copilot`をつけてプルリクエストにコメントすると自動的にその修正を行なってくれます。
![スクリーンショット 2025-06-18 22.09.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3367262/5313b7de-e578-464f-8b5b-a6884322bd2d.png)

## 使ってみた感想
実際に何度か使ってみると、簡潔な指示でもある程度のソースを作成してくれます。
しかもレビュー段階でエラーが出ていたり、もっとこうして欲しいなどあればその行を選択してCopilotに指示すればいいので、かなり今までのCodingでやっていたソースを実際に書くという作業が要らなくなりそうだと感じました。

個人的には、実際にCopilotという仕事仲間と一緒に実装してる感覚にもなれるので、楽しさも増してきます。

## まとめ
Copilot Coding agentはまだプレビュー段階ではありますが、使ってみてとても優秀で指示も細かく行えます。
しかもPRも自動で作成されるため、やることはレビューのみという、もう開発はこれでいいのでは？と思わせるものになってます。

今後、この機能がさらに向上すると、コーディングせずに自分が作りたいものを細かく書き出すだけでアプリが誰でも作れるようになるでしょう。
【SadServers学習メモ #5】使ったコマンドまとめ（awk）

# 初めに
Linuxの学習目的で`SadServers`を始めました。
備忘のために使用したコマンドをアウトプットします。

# SadServersとは
Linuxの学習サイト。
架空のサーバを題材とし、その管理者となって与えられた依頼をこなしていく。
実際にコマンドを使って作業をすることで、実践的なスキルが身につくことが期待できる。

https://sadservers.com/

# 今回のお題
## タイトル
["Lhasa": Easy Math](https://sadservers.com/newserver/lhasa)

## 詳細
* ある数列の平均を求める
* 数列は以下のように2列になっており、2列目の値の平均を求める
* 少数第三位を切り捨て、少数第二位の値で答える

```scores.txt
1 7.4
2 0.4
3 1.6
4 6.2
5 7.6
6 7.7
...
```

## 作業の流れ
* 2列目を抽出し、母数をカウントしておく
* 抽出した数列の合計値を求める
* 平均を求める
* 少数を切り捨てる

# 使ったコマンド
## awkコマンド
おなじみのawkコマンドを使います。


### 二列目の抽出 & 合計取得 $ 母数のカウント
* 変数を扱うことができる
* セミコロンをつけることで複数の処理を実行できる

```sh
$ awk '{s += $2; count++}
```

### 平均を求める & 切り捨て
* 合計÷母数で平均を求める
* `int(ave * 100)/100`で少数第三位を切り捨てた値を取得
* 最小桁数が0の場合でも省略されないよう、`printf "%.2f\n"`で出力形式を指定
```sh
{ ave = s / count; trancation = int(ave*100)/100; printf "%.2f\n", trancation }
```

### ENDでつなげる

```sh
$ awk '{s += $2; count++} END { ave = s / count; trancation = int(ave*100)/100; printf "%.2f\n", trancation }' scores.txt
```

# 終わりに
awk便利ですね。毎回助けられてます。
最初はただ列を抽出するだけのコマンドかと思ってましたが、ちょっとした計算もできるのが便利でよいです。
他の問題でも使えると思うので、また学んだらアウトプットします。

ここまでご覧いただきありがとうございました！
コードレビューの質を高める！〜Looks Good To Me を添えて〜

# コードレビューで見込める効果とレビュイーとして意識すること

「Looks Good To Me みんなのコードレビュー」を読み、これまでの開発経験と照らし合わせながら、コードレビューにおいて特に重要だと感じた点をまとめました。本記事では、レビュイー（レビューを受ける側）の視点から、効果的なコードレビューを実現するために意識すべきポイントを整理しています。

## コードレビューで見込める効果

### 品質向上
- **不具合の早期発見**: 複数の目でコードをチェックすることで、バグや問題を早期に発見
- **可読性への意識向上**: レビューを前提とすることで、読みやすいコードを書く意識が高まる

### チームのコードの理解度向上
コードレビューを通じて、チーム全体でコードベースの理解を深め、属人化を防ぐことができます。

:::note info
この記事では、レビューの仕組みを表す言葉として**PR（プルリクエスト）**を使用しています。GitLabを使用している方は**MR（マージリクエスト）**に読み替えてください。

また、ツール特有の使い方には言及せず、コードレビューというプロセスの考え方に触れています。
:::

## レビュイーとして意識すること

### よいPRとは

良いPRの条件として以下の5つを挙げます。

1. **チケットに関する必要な変更だけが含まれ、関係のない変更が最小限**
2. **変更されたコードが500行以下、変更ファイル数が20未満**
3. **30分程度の短時間でレビューできる**
4. **レビュワーに必要な情報が添えられている**
5. **コードの変更について説明できる、または説明なしで理解できる**

#### 1. チケットに関する必要な変更だけが含まれ、関係のない変更が最小限

実装中に「気になる箇所を直しておこう」という経験は多いでしょう。しかし、関係のない変更が多いとレビュワーは「本実装に影響があったのか？」と都度考える必要があります。

レビュワーは別の実装を中断してレビューすることが多く、すでに脳のメモリを使っています。**余計なコンテキストを省き、レビュワーがスムーズにレビューできるよう、変更は本筋のみに絞りましょう。**

#### 2. 変更されたコードが500行以下、変更ファイル数が20未満

コードの変更行数とファイル数を最小限にすることで、PRのマージまでのスピードを早め、他のブランチとのコンフリクトリスクを減らせます。

#### 3. 30分程度の短時間でレビューできる

重要なのは「レビュワーが30分で納得感を持って承認できるように準備すること」です。つまり**「単位時間あたりのレビュー品質を高めること」**が目標です。

時間が長くなりすぎると、レビュワーの集中力が落ちてしまうため、30分程度を目指します。

#### 4. レビュワーに必要な情報が添えられている

必要な情報を整理することで、レビュー時間を短縮し、今後の開発でのコミュニケーションにも活用できます。

**コードだけには含まれていないドメイン情報**（実装思想、エンドユーザーとのやり取りなど）を適切に伝えることで、未来の開発にも活かせるでしょう。

#### 5. コードの変更について説明できる、または説明なしで理解できる

AIを使うようになって実装スピードは向上しましたが、自身で実装していないコードも増えました。コードレビューでは「意図がわからないコード vs 新しい提案」を比較するため、実装者は自身のPRについて説明できるよう理解を深めることが重要です。

ただし、AIによる実装スピード向上のメリットも大きいため、テストで品質を担保するなど、**品質とスピードのバランスを取ることが大切**です。

## まとめ

効果的なコードレビューは、不具合発見だけでなく、チーム全体の技術力向上とコードベースの品質向上に貢献します。レビュイーとして上記の5点を意識することで、より良いコードレビューサイクルを実現できるでしょう。
【問題解決】グローバル検索でロングテキストエリア項目の値が無視される

グローバル検索でロングテキストエリア項目の値が無視されて困りました。
原因がわかったので、解決方法を共有します。

# 背景
ロングテキストエリア項目の値は、SOQLの検索条件に使用できません。
SOSLを使用して実装することにしました。

# 問題発生
SOSLを使用して、「ロングテキストエリア項目に対象の値を持つ個人取引先レコード」を取得することができません。
![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3255462/67c8a151-bb4f-48c9-ac97-6964dc5d1627.png)

グローバル検索でもレコードを取得することができません。
※グローバル検索は、SOSLを使用していると思う

# 原因
個人取引先の仕様が原因でした。
取引先責任者オブジェクトで作成したロングテキストエリア項目は、
個人取引先レコードの検索対象にならないようです。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3255462/aa5211d5-a0cd-4e0e-ab8f-b304e0f0236c.png)

# 解決方法
取引先オブジェクトでロングテキストエリア項目を作成します。
個人取引先レコードの検索対象になりました。
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3255462/604fbf69-984e-4ee7-afc3-0413e8f74429.png)
ど素人奮闘記#1　webタイマー作った


## 初めてのwebアプリ作ってみた
普段はExcelVBAで生きている人です。
html、css、JavaScriptで、わからないなりにいろいろいじってみた記録です。

#### [エクサタイマー](https://adorable-sprite-16e65b.netlify.app/)
「エクササイズタイマー」
略して「エクサタイマー」として、自分用のサービスを作ってみました。

デスクワーク、創作活動、youtube鑑賞など、座りっぱなしになりがちなすべての人に捧げる「定期的に運動していこうねタイマー」です。


### 何のために作ったのか
健康のためには、「座ったまま過ごす時間が30分以上続く場合は、立ち上がって軽いウォーキングや体操を3分以上行うこと」が望ましいそうです。
しかし、私のように没頭するタイプの人間はそんなこと言っていられません。
定期的に運動をしやすい環境を作るための仕組みとして、指定時間経過で体操動画が出るようなタイマーを作るのはどやねんという発想に至りました。

### 使うと...どうなる？

タイマーが終了すると、下部の再生リストにセットされている動画がランダムで表示されます。

動画リストは、任意のyoutubeアドレスに書き換えてもよし、デフォルト動画のまま使っても良し。
なお、youtubeアドレスに時間指定が含まれている場合にはまだ対応できていません。
これもあって、現状ではアドレスを入力した後は「動画表示確認」ボタンでお試しすることを推奨します。
スマートフォンでの通知音再生等に対応しておらず、現状はPC向けです。

### 作る時に考えたこと　～こだわりという名の言い訳～

キングジムで販売している「ビジュアルバータイマー」を参考に、残り時間はバーと文字で示す形式にしました。

あまり長い時間を指定しないでほしいという意図から、タイマーの時間調整ボタンは1分・5分・15分の3種類としました。
細かすぎる必要性もないと判断し、秒単位の時間調整も取り入れていません。
今すぐ運動したい！と思うときは、「動画表示確認」ボタンで動画だけ表示すればよいでしょうという寸法です。

タイマー完了後に表示する動画のリストは気分で変更できるよう複数用意しています。
動画のランダム表示や複数リスト対応は、飽きっぽい自分のための仕様です＼(^o^)／
入力したURLはローカルストレージに入るので、次回も同じリストが使える（はず）です。

通知音を再生するため、勉強も兼ねてNetlifyを使用して公開してみました。

### 今後の展望
+ UI・UXは伸びしろたっぷりな気がしています。仕組みだけ思いついて勢いで作るタイプなので、デザインを詰め切れていない感じが漏れ出ています。
+ 再生リストに何の動画が入っているのかパッと見で判断できないのが気になります。リストの名称変更ｙ、URLから動画タイトルを取得して表示するなど追加機能として設けたいところ。
+ デスクトップ通知等含めPC向けな仕様で、スマートフォン対応までは到達できていません。どっちでも使えるようにしたいのぅ...というところです。
【Tableau学習メモ】初心者時代にnoteに書き溜めた記事を紹介します（後編）

こんにちは。  
本記事は、**Tableau Data Saber取得前の学習記録**として、初心者時代にnoteにまとめていた内容を紹介するシリーズの**後編**です。

前編では、列と行、フィルター、Visual Best Practiceなどの基本について取り上げました。  
➡ [前編はこちら](https://qiita.com/takeshi_05/items/eda2daa110ebebe5d8f3)

今回は、より実践的な内容である「データ結合」と「条件別売上分析」に関するnote記事を紹介します。

---

## 5. Tableauでデータを結合する方法（JOIN・ブレンド・リレーションシップ）  
🔗 [note記事はこちら](https://note.com/ntakeshi_wa/n/n3217dc3d0ec8)

Tableauでは、複数のデータソースを扱う際に、以下のような手法があります：

- JOIN（内部結合・外部結合など）
- データブレンド
- クロスデータベース結合

初心者のころは「どれも似たようなものでは？」と感じていましたが、  
実際に使っていくと、それぞれ**動作の違い**や**使いどころ**があることに気づきます。

このnoteでは、

- 結合方法ごとの特徴と違い
- 表示結果やパフォーマンスへの影響
- 「なぜこの手法を選ぶのか？」という考え方

について、自分なりに整理してまとめています。

---

## 6. 色々な条件で売上を見たいときの工夫（複数条件・パラメータの活用）  
🔗 [note記事はこちら](https://note.com/ntakeshi_wa/n/nbab9cd290603)

Tableauを実務的に使いはじめると、**条件を切り替えて分析したい**というニーズが増えてきます。

このnoteでは、複数条件を使った売上データの絞り込みについて紹介しています。

分析の幅を広げる第一歩として、「こういうこともできるんだ」と感じた体験を言語化しています。

---

## 📝 まとめ

初心者の頃に試行錯誤しながら書いたnoteは、**自分自身の理解を深める助け**になりました。  
今読み返すと、粗削りな部分もありますが、「どこでつまずいたか」が分かることで、後から見ても良い学習素材になっています。

Tableau学習中の方にとって、少しでもヒントになれば嬉しいです。
【Tips】ベクトルの大きさ変更を最適化

今回の内容は実行時に少し速度が速くなる小ネタ程度の内容です。
C++のコードを交えますが、考え方はどの言語でも使えるものとなります。
# ベクトルの大きさを変更するには?
ベクトルの大きさのみを変更したい場合、すべての要素に同じ値を乗算か除算するScaleという処理を使用することになります。
本記事では三次元ベクトルで統一して考えてみたいと思います。
## n倍のScaleの式
```math
\begin{pmatrix}x' & y' & z' \end{pmatrix}
=
n\begin{pmatrix}x & y & z \end{pmatrix}
```
## 1/nのScaleの式
```math
\begin{pmatrix}x' & y' & z' \end{pmatrix}
=
\begin{pmatrix}x & y & z \end{pmatrix} / n
```
コードで書いてみたいと思います。
## n倍のScaleのコード
```c++:ScaleMul.cpp
#include <iostream>
#include <vector>
//メイン関数
int main() {
	std::vector<float> vec = { 1.3f, 2.3f, 3.3f };
	// ベクトルの要素を出力
	std::cout << "befor:";
	for (auto it = vec.begin(); it != vec.end(); ++it) {
		std::cout << *it << " ";
	}
	std::cout << std::endl;

	//ベクトルの大きさを変更、今回は2倍する。
	for (auto it = vec.begin(); it != vec.end(); ++it) {
		(*it) *= 2;
	}

	// ベクトルの要素を出力
	std::cout << "after:";
	for (auto it = vec.begin(); it != vec.end(); ++it) {
		std::cout << *it << " ";
	}
	std::cout << std::endl;

	system("pause");
	return 0;
}
```
```:result
befor:1.3 2.3 3.3
after:2.6 4.6 6.6
続行するには何かキーを押してください . . .
```
## 1/nのScaleのコード
```c++:ScaleDiv.cpp
#include <iostream>
#include <vector>
//メイン関数
int main() {
	std::vector<float> vec = { 1.3f, 2.3f, 3.3f };
	// ベクトルの要素を出力
	std::cout << "befor:";
	for (auto it = vec.begin(); it != vec.end(); ++it) {
		std::cout << *it << " ";
	}
	std::cout << std::endl;

	//ベクトルの大きさを変更、今回は2で割る。
	for (auto it = vec.begin(); it != vec.end(); ++it) {
		(*it) /= 2;
	}

	// ベクトルの要素を出力
	std::cout << "after:";
	for (auto it = vec.begin(); it != vec.end(); ++it) {
		std::cout << *it << " ";
	}
	std::cout << std::endl;

	system("pause");
	return 0;
}
```
```:result
befor:1.3 2.3 3.3
after:0.65 1.15 1.65
続行するには何かキーを押してください . . .
```
# どう最適化する?
実はコンピュータは除算が苦手で、四則演算の中で最も遅いです。
有識者の記事を参考にしますと、乗算が4クロックなのに対し、除算は最大で97クロック、速度に20倍近くの違いがあることになります。

参考記事↓

https://qiita.com/saka1_p/items/6400e5cedea0b3c286c9

人間の感覚からするとほとんど誤差がないですが、これが3Dゲームなどで毎フレーム何回も行う処理となると、やはり最適化したくなりますよね。
# 逆数を使って除算の回数を減らそう
除算の結果と、逆数を乗算したものの結果は同じであったはずですよね。
### 除算
```math
a/b = \frac{a}{b}
```
### 逆数の乗算
```math
a\frac{1}{b} = \frac{a}{b}
```
逆数は、``1``を``n``で除算すれば求められましたよね。
早速書いてみましょう。
```c++:ScaleDiv.cpp
#include <iostream>
#include <vector>
//メイン関数
int main() {
	std::vector<float> vec = { 1.3f, 2.3f, 3.3f };
	// ベクトルの要素を出力
	std::cout << "befor:";
	for (auto it = vec.begin(); it != vec.end(); ++it) {
		std::cout << *it << " ";
	}
	std::cout << std::endl;

	//ベクトルの大きさを変更、今回は2分の1倍にする。
	float scaler = 1.0f / 2.0f;
	for (auto it = vec.begin(); it != vec.end(); ++it) {
		(*it) *= scaler;
	}

	// ベクトルの要素を出力
	std::cout << "after:";
	for (auto it = vec.begin(); it != vec.end(); ++it) {
		std::cout << *it << " ";
	}
	std::cout << std::endl;

	system("pause");
	return 0;
}
```
```:result
befor:1.3 2.3 3.3
after:0.65 1.15 1.65
続行するには何かキーを押してください . . .
```
除算でScaleしたのと同じ結果ですが、除算の回数を3回から1回に減らせました。
演算の回数は多くなっていますが、除算が乗算の約20倍遅いことを考えると、毎フレーム何度もやる処理であった場合、処理を最適化できたといえるでしょう。
# 総括
- 除算は速度が遅い
- VectorのScaleのように、すべての要素を同じスカラーで除算する場合、逆数を求めてからそれで乗算を行った方が処理の速度が速くなる
【Tableau学習メモ】初心者時代にnoteに書き溜めた記事を紹介します（前編）

こんにちは。  
現在は **Tableau Data Saber** を取得済みですが、ここに至るまでには「何が何だか分からない」状態からスタートし、少しずつ試行錯誤を重ねてきました。

この記事では、**Data Saber挑戦中の初心者時代にnoteに書いた学習メモ**を紹介します。自分自身の備忘録として書いたものですが、Tableauを学び始めたばかりの方の参考になれば嬉しいです。

---

## 1. Tableauの「列」と「行」について整理したメモ  
🔗 [note記事はこちら](https://note.com/ntakeshi_wa/n/ne34c16e39670)

Tableau初心者にとってまず戸惑うのが「列」「行」の概念。Excelとの感覚の違いに混乱しつつも、「行シェルフ」「列シェルフ」にどうフィールドを置くかでグラフの形が大きく変わることを、実際に動かして理解していった記録です。

---

## 2. Tableauの「フィルター」って、どう使えばいい？  
🔗 [note記事はこちら](https://note.com/ntakeshi_wa/n/naa781e1b5b81)

フィルターは便利だけど、Excelと同じ感覚でフィルターを使おうとすると、上手くいかない事が多くて最初は混乱しました。
このnoteでは、ExcelとTableauのフィルターへの考え方の違いについて記載しています。

---

## 3. Visual Best Practice（前編）：見やすいダッシュボードって何？  
🔗 [note記事はこちら](https://note.com/ntakeshi_wa/n/n4d784f3c21f5)

「いいダッシュボードってどう作るの？」と悩み始めたときに出会ったのが、**TableauのVisual Best Practice**。

このnoteでは前編として、以下のような基本的なルールを紹介しています。

- 可視化をする目的について
- Preattentive Attributesについて
- データのタイプとPreattentive Attributesとの相性について 

初心者のうちにこの考え方を知っておくと、Vizの質が一段上がると感じました。

---

## 4. Visual Best Practice（後編）：配色や余白の工夫など  
🔗 [note記事はこちら](https://note.com/ntakeshi_wa/n/n53399a02e642)

後編では、ダッシュボードの**見やすさ・整い方**に直結する工夫を紹介しています。

- 配色のルール（色数・意味のある使い方）  
- コンテキストについて 
- 探索型・説明型ダッシュボードについて

小さなポイントでも意識することで、見やすさが格段に変わるという学びがありました。

---

## 📌 次回予告（後編）

次の記事では、以下のnote記事を紹介予定です：

- Tableauでデータを結合する方法
- 色々な条件で売上を見たい

後編では、より実務に近い内容や、分析の切り口を変える工夫を紹介していきます。

---

## 📝 まとめ

初心者のときに書いたnoteを振り返ると、「何が分かっていなかったか」がよく分かります。  
でも、わからないなりに**手を動かして整理し、言葉にしてきた積み重ね**が、今の自分の力になっています。

これからTableauを学ぶ方にとって、この記事がヒントや励みになれば幸いです。
素数の個数



今回はPaizaの「素数の個数を数える」問題に挑戦！

久しぶりだから忘れてたけど、「フラグ」を使うのがポイントだった！


<br>

## 問題概要

整数 N が与えられるので、2 以上 N 以下の素数の個数を求めよ。

<br>

入力例：

    100

出力例：

    25

<br>

https://paiza.jp/works/mondai/double_roop_problems/double_roop_problems__prime_number_easy

<br><br><br>

## ✅ OK例①：引き算スタイル
```js
let primeCount = N - 1;
for (let i = 3; i <= N; i++) {
  for (let j = 2; j < i; j++) {
    if (i % j === 0) {
      primeCount--;
      break;
    }
  }
}

console.log(primeCount);
```

### 💡ポイント：引き算スタイルの考え方

- 最初に `primeCount = N - 1` として、2 〜 N までの全てを「仮の素数」としてカウント（1は素数ではないので除外）。
    
- 外側のループ `i` は 3 からスタート。( 2 は最初から素数として数えられている)
    
- 内側のループ `j` は、2 から `i - 1` まで回す。1 と i 自身は必ず割り切れるので除外している。
    
- `i % j === 0` で割り切れたら、その時点で `i` は素数じゃない → `primeCount` を 1 減らしてループ終了（`break`）。


<br><br>

## ✅ OK例②：フラグ スタイル
```js
let primeCount = 0;
for (let i = 2; i <= N; i++) {
  let isPrime = true;
  for (let j = 2; j * j <= i; j++) {
    if (i % j === 0) {
      isPrime = false;
      break;
    }
  }
  if (isPrime) primeCount++;
}

console.log(primeCount);
```

### 💡ポイント：フラグ スタイルの考え方
- `isPrime = true` で始めて、1 個でも割り切れたら `false` にする。
    
- 内側のループの条件は `j * j <= i`。割る数は `i` の平方根まででOK！（これで大幅にループ数が減る）
    
- 割り切れた瞬間に `isPrime = false` として `break` → 無駄なループを避けて高速化。
    
- ループ後に `isPrime === true` のときだけ、`primeCount++` でカウントする。


<br><br><br>

## ✍️気づきメモ & まとめ

- 割り切れる＝素数じゃない という考え方。
    
- 素数かどうかのチェックは全部の数じゃなくて、√ i まででOKだった！（約数の考え方の応用）
    
- フラグ管理（`isPrime = true/false`）は思ってる以上に読みやすい
    
- `for` ループ内に `break` を使うと、無駄なループを防げて時短になる

- 数学の基本知識（素数の定義）が、コードの理解にも役立つ




<br><br><br>[僕の失敗談(´;ω;｀)と解決法🐈](https://paizabeginner.wordpress.com/2025/06/18/paiza%e3%81%a7%e5%9f%ba%e6%9c%ac%e3%83%9e%e3%82%b9%e3%82%bf%e3%83%bc%ef%bc%9a%e7%b4%a0%e6%95%b0%e3%81%ae%e5%80%8b%e6%95%b0/)
～【社内講習】Excel講習オンライン～

# 初めに
Excel講習の講師を担当している@harris1992です。
オブジェクティブグループ(以下、OBG)で毎月行われている講習会の様子をお届けする記事となります。
今回はExcelの学習内容の一部をご紹介いたします。

# Excel講習とは?
OBGで毎月第2土曜日11:00～19:00に実施している講習会となります。
基本的にオンライン開催となりますが、3ヶ月に1回OBG本社にてオフラインでの開催も行っております。
PC初心者からある程度触ったことがある方まで様々な方が受講されるので、Excelの画面の見方や簡単な操作方法から業務で使用するような関数、VBAの学習まで受講者の学習状況に合わせて幅広い範囲の学習を行っております。
また、Excel講習の他にもフロントエンド講習、SQL講習も開催されており、受講者が受講したい講習を選択して参加できる形となっております。

# Excel、VBA講習
今回は2名の方に御参加いただきました。
1名は初参加とのことだったので、Excelの基礎から説明を行いました。
また、もう1名の方は継続して参加していただいている方なので、自分で取り組んでいる課題を行っていただき、進捗状況の確認やアドバイスを適宜行う形で取り組んでいただきました。

# 関数
今回は初めて参加の為、よく使用する関数をメインに説明を行いました。

主な説明を行った関数
SUM関数
=SUM（セル範囲）

SUMIF関数
=SUMIF（範囲,検索条件,合計範囲）

AVERAGE関数
=AVERAGE（セル範囲）

IF関数
=IF（条件式,[真の場合],[偽の場合]）

VLOOKUP関数
=VLOOKUP（検索値,範囲,列番号,検索方法）

# 練習問題
最後に講習内で学習した内容を基に、自分で簡単な関数を作成する問題を実施しております。
実際に自分で関数を作ることで、学習した内容の理解を深めていただいております。

# おわりに
Excelは現場で使用する機会が多いので、この機能はどうやってやれるかなと気になることがあったら是非学習してみてください。

***
オブジェクティブグループでは X（旧Twitter） の投稿も平日毎日行っています！
IT 関連の小ネタや便利技から、日常のアニメ・ゲーム布教なども幅広く投稿してるので、
ご興味のある方は是非フォロー・いいねをお願いします。

https://x.com/obg_ocr
Slackの絵文字にはNuko Emotes Archiveがおすすめ

2000年代風でレトロでかわいい絵文字を探していたところ、次のサイトを見つけました。膨大な絵文字があって様々なケースをカバーできます。

https://nukochannel.neocities.org/


![Caramelldansen Heart.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127762/aad89567-5629-4d83-9fff-8d639c5a84f1.gif)

かわいい。
Swiftの@Publishedとは？　@Publishedについて簡単に説明してみました！

この記事では、Swift初心者の方向けに @Published の意味と使い方をわかりやすく解説します！

@Publishedってなに？
--
@Published は、値の変化を通知できるようにするプロパティラッパーです。

具体的には、ある変数の値が変わったときに、それを自動的に監視している画面（View）に伝えてUIを更新してくれるのが @Published の役割です。

いつ使うの？
---
@Published は、ObservableObjectを継承したクラスの中で使うのが基本です。

そして、このクラスのインスタンスを、SwiftUIの @StateObject や @ObservedObject と組み合わせて使うと、変数の値の変化に応じてUIが自動で更新されます。


```swift
import SwiftUI

class CounterViewModel: ObservableObject {
    @Published var count = 0
}

struct ContentView: View {
    @StateObject var viewModel = CounterViewModel()

    var body: some View {
        VStack {
            Text("カウント: \(viewModel.count)")
            Button("増加") {
                viewModel.count += 1
            }
        }
    }
}
```

**実際に何が起こってるというと**
まず
1 viewModel.count の値が変わると…

2 @Published が「値が変わったよ！」と通知を送る

3 @StateObject がそれを受け取り、UIを再描画！

つまり、開発者が何もしなくても、画面が勝手に最新の状態になるのです。

@State とは何が違うの？
---
@State → View内部で完結する状態管理

@Published → ViewModelの状態をUIに伝えるための仕組み

アーキテクチャでいうと、@Published は「ロジック（ViewModel）」と「見た目（View）」を分けるために使います。


ここで注意点
---
- @Published を使うクラスには 必ず ObservableObject をつける

- 画面側では @StateObject か @ObservedObject を使って受け取る

- 構造体（struct）では使えない → クラス（class）専用

まとめ
---
| 特徴     | 内容                                |
| ------ | --------------------------------- |
| 機能     | 値の変更を監視して、UIに通知する                 |
| よく使う場所 | `ObservableObject` を継承したクラスのプロパティ |
| UI更新   | 値が変わると自動でViewが更新される               |


以上で@Publishedについて簡単に説明してみました、ぜひ参考にしてみてください！✌️
Geminiでゴーレムと遊ぶ魔法少女を描いてみた。

# 概要

Geminiでゴーレムと遊ぶ魔法少女を描いてみました。

# 実装

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

```
水のゴーレムと遊ぶ魔法少女を描いてください。
```

![水のゴーレムと遊ぶ魔法少女_20250618.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192024/f65f9705-5ced-42f5-a2fe-0a03510782ea.png)

# まとめ

何かの役に立てばと。
Linuxを基本からまとめてみた【リポジトリとパッケージ管理(Debian系)】

## パッケージ管理方式
#### パッケージとは？
- ファイルのまとまり

#### リポジトリとは？
- パッケージを公開しているサーバ

#### ダウンロードとインストールとは？

| ダウンロード　| インストール |
| --- | --- |
| パッケージを取得する | パッケージを使えるようにマシンを整える |

#### apt-getコマンド
- リポジトリを利用してパッケージをインストールなど
- apt-get[サブコマンド][キーワード(パッケージ名を指定)]

| サブコマンド | 説明    |  
| --- | --- | 
|update |パッケージ情報を更新 | 
|upgrade | パッケージを更新 | 
|install |パッケージをダウンロード、インストール | 
|remove |設定ファイルを残してパッケージを削除 | 
|purge |設定ファイルを含めてパッケージを完全削除 | 
|dist-upgrade | 必要に応じてパッケージ完全削除も含めてシステム全体を更新 | 

#### apt-cacheコマンド
- リポジトリを活用してパッケージを検索
- apt-cache[サブコマンド][キーワード(パッケージ名を指定)]
| サブコマンド | 説明    |  
| --- | --- | 
|search |パッケージを検索 | 
|show | パッケージの情報を表示| 

#### aptコマンド
- リポジトリを利用してパッケージを操作
- apt[サブコマンド][キーワード(パッケージ名を指定)]

| サブコマンド | 説明    |  
| --- | --- | 
|update |パッケージ情報を更新 | 
|upgrade | パッケージを更新 | 
|install |パッケージをダウンロード、インストール | 
|remove |パッケージを削除 | 
|full-upgrade |必要に応じてパッケージ完全削除も含めてシステム全体を更新 | 
|list | パッケージの一覧を表示 | 
|search |パッケージを検索 | 
|show | パッケージの情報を表示| 

## debパッケージのインストール
#### apt update
- パッケージ情報の更新
- パッケージの更新はせず、パッケージの「情報」を更新する
- マシンに保存してある、リポジトリに関連するデータ（リポジトリのメタデータ）を更新する

#### apt upgrade
- パッケージの更新
- マシンに保存されているパッケージの情報をもとに、パッケージを更新する
- 「apt update」をせずに、「apt upgrade」を実行すると、パッケージを最新のものに更新できないことがある

#### パッケージ情報を更新する
```
$ sudo apt update
```
#### パッケージをインストールする
```
$ sudo apt install [パッケージ]
```

## 依存関係とその解決
####  依存関係とは？
- パッケージを利用するために他のパッケージも必要になる関係のこと

####  依存関係を解決するとは？
- パッケージが依存している全てのパッケージを用意すること
- コマンドで依存関係を解決できる

####  なぜ依存関係が生まれるのか？
- パッケージの処理が他のパッケージを前提としている時

## debパッケージの更新
 - deb パッケージを更新する手順は、下記の 2 ステップが必要
#### パッケージ情報を更新する
```
$ sudo apt update
```
#### パッケージを更新する
```
$ sudo apt upgrade
```
## apt 系のコマンドの設定ファイル
```
/etc/apt/source.list
```
#### apt-fileコマンド
- ファイルの名前の一部から、パッケージを検索
- apt-file サブコマンド [キーワード(パッケージ名を指定)]

| サブコマンド | 説明 |  
| --- | --- | 
|search |パッケージを検索 | 
|show | パッケージの情報を表示| 

- インストールとコマンドのダウンロードが必要
```
$ sudo apt update
$ sudo apt install apt-file
```
- 使うには　updateサブコマンドの実行が必要
```
$ sudo apt-file update
```
- 検索
```
$ sudo apt-file search libwrap
$ sudo apt-file search パス名(もしくはファイル名)
```
## dpkgコマンドによるdebパッケージ管理
#### dpkgコマンド
- ファイルの名前の一部から、パッケージを検索
- dpkg オプション [キーワード(パッケージの名前を指定(-sの時はファイル名前)]

| サブコマンド | 説明 |  
| --- | --- | 
|-i(--install) |パッケージをインストール | 
|-r(--remove) | パッケージを削除| 
|-P(--purge) |既設ファイルも含めて削除 | 
|-l(--list) |インストール済みのパッケージの一覧を表示| 
|-L(--listfiles) |インストール済みのファイルの一覧を表示 | 
|-s(status)  | パッケージの情報を表示| 
|-S(--search) |ファイルのインストール元パッケージの検索 | 

## debパッケージの管理
#### treeパッケージをダウンロードする方法
```
$ apt download tree
```
#### dpkg-reconfigureコマンド
- パッケージを再設定
- dpkg-reconfigure [キーワード(パッケージの名前を指定]



## 参考サイト
[新・Linux入門編5(LinuC対策版): リポジトリとパッケージ管理 (Debian系)](https://paiza.jp/works/linux/new-primer/linux-new-primer-5)
Cursorでプロジェクト管理する時に重宝しているプロンプト

## 前提~プロジェクトページの重要性~
私はCursorを使ってプロジェクト管理をすることが多い。

Cursorでプロジェクト管理をする時に重要になるのは常にプロジェクトの全体像や前提、現在の進捗を把握できるようにすることだ。

そのために以下のようなディレクトリ構造を作って、そのプロジェクトの大元になるプロジェクトページを作る必要がある。

そのためのプロンプトを紹介する。
## プロンプト
```
    ## 指示
    以下のタスクをこなしてほしい
    1. まず、ユーザーに始めようとしているプロジェクトについて質問をしてほしい。端的なプロジェクトの説明をするため、また、{## 記載内容}の内容で記載できるところまで記載するための質問であることを重視してほしい。
    2. 新しいフォルダを作成する。フォルダの名前は"(2桁の連番)_(プロジェクト名)_pjtページ"という構成である。
    3. フォルダの中に次の二つを作成する
    	1. {## 記載内容}を搭載しているプロジェクトページをmd形式で作成する
    	2. "(プロジェクト名)_議事録"という名称のフォルダ
    
    ## 記載内容
    プロジェクトページは以下のような項目、文面。「## このドキュメントについて（運営方針）」のところにある文面は{}で括られているところ以外はそのまま記述してほしい。
    ```
    ## このドキュメントについて（運営方針）
    - {端的なプロジェクトの説明があり}、そのためのプロジェクトページである。
    - プロジェクトページとは、「そのドキュメントを見れば、プロジェクトの目的、前提、目標・KPI、進捗がはっきりとわかる」というドキュメントを目指す。よって、以下のことを重要視する必要がある。
        - プロジェクトページは端的に、わかりやすく、視認性よく記述されている必要がある。
        - 詳細に関しては別のファイルのリンクを用意し、そこに飛べばわかるという設計にする    
    - このドキュメントを参照して作成したファイルや相談に関しては、進捗にそのファイルを作成した背景とそのファイルへのリンクを記述して、離散しないようにしてほしい。
    - 基本的にこのドキュメントに準拠して作成するファイルはmdファイルである。それ以外は臨機応変に対応してほしい。また、同一ディレクトリにある「議事録」ファイルに作成して。その際のファイル名は「yyyymmdd_(ファイル名).md」というファイル名にしてほしい。
    ## 目的
    ## 前提
    ## 目標やKPI
    ## 進捗一覧
    ```
```
## このプロンプトでできる成果物
```
01-プロジェクト/
├── プロジェクト概要.md
└── 01-議事録/
    ├── YYYYMMDD_議題1.md
    ├── YYYYMMDD_議題2.md
    └── YYYYMMDD_議題3.md
```
## まとめ
Cursorを使用することで、開発だけじゃなくてドキュメント作成を爆速でこなすことができる。

この記事を参考にしてもらいながら、生成AIを自分の仕事に取り入れてもらえれば幸い。
Angularで画像が表示されない場合の設定確認

# はじめに
以下の通りパスを指定しても画像がブラウザに表示されない場合の対処方法（パスには画像があることを確認済）
```diff_tsx:card.html
  <img
    src="assets/images/1.jpg"
    alt="image"
  />
```

# 解決方法
angular.jsonの設定漏れを確認する

```diff_json:angular.json
            "assets": [
              {
                "glob": "**/*",
                "input": "public"
              },
+              "src/assets"
            ],
```

↑の通り、assets配列にsrc/assetsを追加して、画像認識させるように修正し、サーバー再起動すればOK

# おわりに
こんな事象に20分ぐらいかけてしまった...（先は長そう...）

## JISOUのメンバー募集中🔥
プログラミングコーチングJISOUではメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか？
気になる方はぜひHPからライン登録お願いします！👇

https://projisou.jp/
Fultterの環境はDockerで準備する

# 初めに
Fultterで開発する環境構築はDockerを併用してWindowsにインストールすることを極力抑えてサクっと構築します。
# 代表的な手順

## 1. Docker Desktopのインストール
- [Docker公式サイト](https://www.docker.com/products/docker-desktop/)からDocker Desktop for Windowsをインストールします。

## 2. Flutter用Dockerイメージの利用

公式Flutterイメージやコミュニティイメージを利用します。  
例: [cirrusci/flutter](https://hub.docker.com/r/cirrusci/flutter)

```bash
docker pull cirrusci/flutter:stable
```

## 3. プロジェクトディレクトリの作成
```bash
mkdir flutter_project
cd flutter_project
```

## 4. Dockerコンテナの起動
プロジェクトディレクトリをコンテナにマウントし、bashで入ります。
```bash
docker run --rm -it -v %cd%:/app -w /app cirrusci/flutter:stable bash
```
※PowerShellの場合は`%cd%`、コマンドプロンプトの場合は`%cd%`、Git Bashの場合は`$(pwd)`に置き換えてください。

## 5. Flutterプロジェクトの作成
コンテナ内で以下を実行します。
```bash
flutter create .
```

## 6. 開発・ビルド

コンテナ内で通常通りFlutterコマンドが使えます。

```bash
flutter pub get
flutter run
flutter build apk
```

## 7. エディタの利用

- VS CodeやIntelliJなどはWindows側で利用し、`flutter_project`ディレクトリを編集します。
- コード編集はローカル、ビルドや実行はDocker内で行います。

## 8. 注意点

- エミュレータ(Android/iOS)はDocker内から直接起動できません。  
  → 実機デバッグやWebターゲットでの開発が現実的です。
- Webターゲットの場合は`flutter run -d web-server`でWebアプリとして動作確認できます。
---

### まとめ

- Docker Desktopをインストール
- cirrusci/flutterイメージを使い、プロジェクトディレクトリをマウントして開発
- エディタはローカルで利用、ビルド・実行はDocker内で

これでWindowsへのインストールを最小限に抑えたFlutter開発環境が構築できます。
Cursorで登録しておくと便利な設定

## このドキュメントについて

自分がCursorRulesに登録していて便利だった機能をここにまとめておく。
※適宜更新をしていこうと思います。
## Cursor Rules
### 常に日本語で回答させる
```
Always answer in Japanese.
```
何も設定せずにCursorを使っていると、英語などで回答をしてしまい、Token数の無駄遣いにつながる。よって以下を設定しておこう。
### 現在の時間を取得する
```
Always run path/to/getDate.js to know what time it is at first.
```
LLMのモデルは「現在時刻」を取得するのが苦手。これを補助しよう。
用途としては
- ファイル名の先頭に`yyyymmdd`をつけて作成する
- PMの際にスケジュールを立てる補助をしてもらう
```getDate.js
/**
 * 現在日時を 'YYYY-MM-DD HH:mm:ss' で返すユーティリティ
 * @param {Date} [baseDate=new Date()] - 任意の Date を受け取ってフォーマットも可能
 * @returns {string}
 */
function formatDateTime(baseDate = new Date()) {
    const pad = (n) => String(n).padStart(2, '0');
    return [
      baseDate.getFullYear(),
      pad(baseDate.getMonth() + 1),
      pad(baseDate.getDate()),
    ].join('-') + ' ' +
    [
      pad(baseDate.getHours()),
      pad(baseDate.getMinutes()),
      pad(baseDate.getSeconds()),
    ].join(':');
  }

module.exports = {
  formatDateTime
};
  
if (require.main === module) {
  console.log(formatDateTime());
}
  
```
## MCPサーバー
### youtubeのスクリプトを取得するMCPサーバー
```mcp.json
{
  "mcpServers": {
    "mastra": {
      "command": "npx",
      "args": ["-y", "@mastra/mcp-docs-server@latest"]
    },
    "youtube": {
      "command": "npx",
      "args": [
        "-y",
        "@anaisbetts/mcp-youtube"
      ]
    }
  }
}
```
SQL Serverで自己結合をして重複行を削除する

# .1 はじめに
* SQL Serverで重複行の削除をDISTINCT, GROUP BY、副問合せを使用せずに行いたい
* SQLの自己結合を使用して重複行を削除したい

# 2. 開発環境
* SQL Server 2022

# 3. テストデータ
* Sales (売上)

| ProductID | SaleDate | Amount |
| :---: | :---: | :---: |
| 100 | 2025/01/01 | 100 |
| 100 | 2025/01/02 | 200 |
| 100 | 2025/01/03 | 300 |
| 200 | 2025/02/01 | 500 |
| 200 | 2025/02/02 | 600 |

# 4. SQLサンプル
* SaleDate(売上日)が最新の行のみ取得して、重複行を削除する

```SQL
SELECT
    Sales1.*
FROM
    Sales Sales1 
    LEFT JOIN Sales Sales2 
        ON Sales1.ProductID = Sales2.ProductID 
        AND Sales1.SaleDate < Sales2.SaleDate; 
WHERE
    Sales2.SaleDate IS NULL;
```

* 処理結果

| ProductID | SaleDate | Amount |
| :---: | :---: | :---: |
| 100 | 2025/01/03 | 300 |
| 200 | 2025/02/02 | 600 |

# 5. 処理の流れ
## 5.1. Sales (売上)を自己結合する
* 結合条件の符号を変更すると最初、最後を切り替えできる

```SQL
SELECT
    Sales1.*
    , Sales2.*
FROM
    Sales Sales1 
    LEFT JOIN Sales Sales2 
        ON Sales1.ProductID = Sales2.ProductID 
        AND Sales1.SaleDate < Sales2.SaleDate  -- 最後を取得
--        AND Sales1.SaleDate > Sales2.SaleDate  -- 最初を取得
```

* 処理結果

| ProductID | SaleDate | Amount | ProductID_1 | SaleDate_1 | Amount_1 |
| :---: | :---: | :---: | :---: | :---: | :---: |
| 100 | 2025/01/01 | 100 | 100 | 2025/01/02 | 200 |
| 100 | 2025/01/01 | 100 | 100 | 2025/01/03 | 300 |
| 100 | 2025/01/02 | 200 | 100 | 2025/01/03 | 300 |
| 100 | 2025/01/03 | 300 | NULL | NULL | NULL |
| 200 | 2025/02/01 | 500 | 200 | 2025/02/02 | 600 |
| 200 | 2025/02/02 | 600 | NULL | NULL | NULL |

## 5.2. 結合できない行のみ取得する（重複行を削除）
```SQL
SELECT
    Sales1.*
    , Sales2.*
FROM
    Sales Sales1 
    LEFT JOIN Sales Sales2 
        ON Sales1.ProductID = Sales2.ProductID 
        AND Sales1.SaleDate < Sales2.SaleDate  -- 最後を取得
--        AND Sales1.SaleDate > Sales2.SaleDate  -- 最初を取得
WHERE
    Sales2.SaleDate IS NULL;
```

* 処理結果

| ProductID | SaleDate | Amount | ProductID_1 | SaleDate_1 | Amount_1 |
| :---: | :---: | :---: | :---: | :---: | :---: |
| 100 | 2025/01/03 | 300 | NULL | NULL | NULL |
| 200 | 2025/02/02 | 600 | NULL | NULL | NULL |

# 6. 参考文献

https://beagle-dog.com/sql-server-self-join/
【忘備録】Bambu P1SでTPEフィラメントがちぎられる話

# はじめに
とある理由で，P1Sでエラストマー系のマテリアルを出力しようとしたのですが，どうやら1キロスプールそのままだと重すぎてエクストルーダが引きちぎってしまうようです．
髪の毛みたいに細いものが形だけ維持されて出力されるので，改善しました．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628829/89cb5975-aace-4934-82b3-aa23a9cd7ec0.png)
下のほうのような感じで隙間多めで印刷されるのです・・・

# ハウツー
そもそも，今まではK1 MaxのPTFEチューブをエクストルーダから抜いて天板も外して，上からマテリアルを供給していました．ですが，今年度新しくBambuを3台導入したので，K1 Maxにはその役を外れてもらい，P1Sにやってもらうことにしました．
なので，P1Sに限らず，エラストマー・ポリウレタン系のマテリアルは総じて引きちぎられる可能性があるので，うまいこと改善する必要があるのです．

本題に入りますが，ハウツーは
- ベアリング付きのスプールホルダーを設計
- 印刷
- 組み立てる

というわけです．

# やってみよう
## 設計
Fusion 360で設計しました．
各メーカのスプールの内径を図る必要がありますが・・・ここを参考にするのもいいかと思います．
が，eSUNに限ってはマテリアルによっては径が違うことがあるようなので注意が必要でしょう．
https://woodencaliper.hatenablog.com/entry/2021/09/05/223049

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628829/36844831-0667-4b57-999f-5938a703f285.png)
スプールの軸
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628829/ae77ecdd-a5e7-4358-a990-9e9142d6cab7.png)
スタンド（薄すぎたかも）
データはDriveに乗せておきます．
https://drive.google.com/drive/folders/1Z3-ejoyKcMMPtdVVEegcEhhoaawSItGl?usp=sharing

## 印刷
K1 Maxで印刷しました．特に問題はなし．
PLAで印刷．

## 組み立てる
こんな感じに組みあがりました．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628829/781f6bb2-37b6-4b60-8361-beee446dfdc1.png)
軸はφ12 アルミ棒
# 結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628829/9574e0db-0e76-4343-88b5-1cdb99b4b860.png)
上手いこと印刷できるようになりました．
Linuxを基本からまとめてみた【パッケージ管理(Homebrew)】

## Homebrewとは？
- macOS用(またはLinux)用パッケージマネージャー

## インストール方法

[Homebrew](https://brew.sh)

## 使い方
#### バージョンを表示するためのコマンド
```
$ brew -v
```
#### バージョンを検索するためのコマンド
```
$ brew search[パッケージ名]
```
#### パッケージをインストールするためのコマンド
```
$ brew install[パッケージ名]
```
#### Githubリポジトリにあるパッケージをインストールできるようにするためのコマン
```
$ brew tap
```

## 参考サイト
[Homebrew】3分でインストールから応用まで徹底解説！！](https://www.youtube.com/watch?v=-dIK6tFiscY)
[zod v4] エラーメッセージをカスタマイズする時の入力値の取り方

2025年5月にzod v4が公開されました。

zod v4ではv3と比較しいくつかの変更点があります。
具体的な変更点は以下の記事が詳しいです。

https://zenn.dev/codeunit/articles/f99e3546c1574a

さて、zod v4では、`ZodError`クラスから入力値を取る方法も変更されています。
`ZodError`のデータをもとにエラーメッセージを組み立てることも多いかと思いますので、本記事では`ZodError`からデータを取得する方法について解説します。


# v3の場合

v3までは、`issue.received`から入力値を取得する事ができていました。

```ts:zod v3
import { z } from "zod";

const Schema = z.object({
  foo: z.number(),
  bar: z.number(),
});

const { success, data, error } = Schema.safeParse(
  { foo: 1, bar: "hoge" },
);

if (!success) {
  for (const issue of error.issues) {
    console.log("code:", issue.code); //=> invalid_type
    console.log("path:", issue.path); //=> [ 'bar' ]
    console.log("期待値:", issue.expected); //=> number
    console.log("入力値:", issue.received); //=> string (入力した値の型が取れる)
  }
}
```

上の例ですと、期待値はnumber型、実際に入力された値はstring型という情報が取得できます。これを元にエラーメッセージを組み立てる事ができます。

# v4の場合

v4からは、`issue.input`から入力値を取得します。
**ただし、parse時に`{ reportInput: true }`を渡す必要があります。**

```ts:zod v4
import { z } from "zod/v4";

const Schema = z.object({
  foo: z.number(),
  bar: z.number(),
});

const { success, data, error } = Schema.safeParse(
  { foo: 1, bar: "hoge" },
  { reportInput: true }, // ここでreportInput: trueを渡さないといけない！
);

if (!success) {
  for (const issue of error.issues) {
    console.log("code:", issue.code); //=> invalid_type
    console.log("path:", issue.path); //=> [ 'bar' ]
    console.log("期待値:", issue.expected); // => "number"
    console.log("入力値:", issue.input); // => "hoge" (入力した値が取れる)
  }
}
```

zod v4では、このように`reportInput`オプションを指定することで`issue.input`から実際に入力された値を取得する事ができます。


エラーメッセージをカスタマイズする際は、これらのデータを元に文字列を組み立てます。

```ts:エラーメッセージの組み立て
const message = `${issue.expected}型じゃなくて……${issue.input}が来た……ってコト！？`;
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678625/f25e721d-86e6-49cf-a281-e8d5080bd300.png)


以上、zod v4でエラーメッセージをカスタマイズする時の入力値の取り方について解説しました。
Apacheの仕組み ざっくり解説

# apacheの仕組みについて解説

apacheってwebサーバで、フロントで動いているなーくらいの認識しかなかった私ですが、今回仕組みについて調査したので、備忘としてまとめます。


### なぜいまさらapacheなのかというと・・・
チャットボットを自作しようとしていて、組み込み対象となるwebサイトを探していた時に今回の調査したwebサーバがapacheで動いていたためでした。

# 大まかな仕組みとしては以下
1. Apache を起動すると
        ```
        /usr/sbin/httpd（実行ファイル）
        ```
        が起動

        
2. 起動時に読み込まれる設定ファイルが
        ```
        /etc/httpd/conf/httpd.conf
        ```

3. httpd.conf の中で指示されているのが
・どこを Web コンテンツとして公開するか → DocumentRoot    
・どのポートで待ち受けるか → Listen
・どのモジュールを使うか → LoadModule
・どのフォルダにどんなアクセス制限をかけるか → <Directory> など
プロが一人で本気でTwitterクローンを作ってみた

私は普段 Railsエンジニアとして働いています。Twitterクローンといえば、TechXXXみたいなプログラミングスクールの最終課題となっていることも多く、ポートフォリオとして日々量産されているアプリケーションの一つだと思います。メンターのアルバイト経験のある方は「入力と出力が出来るようになれば、なんだって作れるから」と、挫折しかけている受講生の方を励ましたりしたこともあるかと思います。

そんな見飽きたTwitterクローンですが、プロのエンジニアである私もポートフォリオのために(?)本気で作ってみました。それが以下のサイトです。

https://freespk.com/

まあ基本はマイクロポスト出来て、いいね、フォローが出来るという普通の Twitter クローンです。Markdown で書けるとか絵文字でリアクション出来るとか多少工夫したところがありますので、気軽に使ってみていただけると嬉しいです。最終的には Wiki と融合した情報サイトを目指しています。

で、個人でサイトを開発して最も大変だったのは「認証」の部分です。本気なので妥協した設計は入れません。それを今から解説していきます。認証は gem に頼らず rails8 の機能のみで作成しています。

## Devise などの既存の認証システムの問題点

仕事では Devise gem を使っていますが、Devise や Sorcery、Rails チュートリアルで作成するユーザー（＝認証）モデルは、大きな問題を抱えていると考えています。

以下の図は、User モデル と Post などの User に関連付けられるコンテンツとの関係を、ざっくりと表したものです。

![Device を使った場合.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87126/499c0e18-2f31-48ae-bb3c-88a7653451a5.png)

User モデルには、認証で使う email, password の他に、コンテンツの表示に使う nickname、サインアップなどの進捗を管理する token, confirmed_at などのカラムがあります。さらにメールアドレスの変更を行う機能があると unconfirmed_email カラムが追加されたり、パスワードロックを行うための locked_at が追加されたりします。

で、User モデルはSNSの基本となるモデルですので、ウェブサービスに機能が追加されるたびに has_many なんちゃらみたいなのがどんどん増えていき、30キロバイトくらいの巨大な user.rb が出来あがることになります。

要は User モデルにすべてを詰め込め過ぎ、モデルの責務が多くなりすぎになりがちです。また、User モデルが「未認証」のような「状態（status）」を持つため、テストや実装が大変になります。

## Freespk で実装した認証システム

これに対し、私が採用した方針は「とにかくモデルを分割する」というものです。Concerns ではありません。テーブルごと分割します。その関係をざっくりと表したものが以下の図になります。

![Device を使わない場合.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87126/69de9406-f25a-4b8a-9c1c-9c42224a15f5.png)

それぞれのモデルがどう動くのかをユーザー登録を例に説明します。

1. 利用者が「ユーザー登録」を行おうとすると Signup レコードと Confirmation レコードが作られます
1. Confirmation モデルが作られると、利用者に確認メールが送信されます
1. token を含んだURLをクリックすると、Confirmation と Signup が confirmed 状態になります
1. Signup が confirmed 状態になると、Authentication レコードと User レコードが作成されます

User は基本的にはコンテンツしか管理しません。has_many の集合体のようなモデルとなります。また、Userレコードには「登録したけど、まだ未認証」みたいな中途半端な status は無いので、せいぜい退会したかどうかだけを管理すれば良くなります。

ちなみに、Signup の部分には PasswordReset や EmailChange などの似た責務を持つモデルが存在します。それらの手続きが完了した場合に、Authentication のカラムを変更するようになっています。

# モデルを分割したことによる利点

ひとつひとつのモデルが小さくなり責務は一つだけなので、修正やテストが楽になります。たとえば単体テストにおいては User レコードと Post レコードを作るだけでOKです。Authenticationレコードを作成したり「confirmed_at がセットされているか否か」を気にする必要はありません。

# モデルを分割したことによる欠点

User モデルと認証にかかわるモデルの間は「疎結合」になっていますが、認証部分は多数のモデルが連携（と言っても一度に関連するのは3つ程度）して、主に callback で状態の変更を伝え合うことになります。たとえば、Confirmation が confirm されたら、次に Signup を confirm して、さらに Authentication を create し、成功したら after_validation で User を build して一緒に save するといったような感じです。

Rails に慣れない方は Service モデルみたいなのを入れたくなるかもしれません（入れてはダメです）。

# Devise 的な設計には他にも問題が...

確認メールのURLをクリックしたら、たとえ誤クリックでも認証されてしまうとか、2要素認証をまともに動かすのは難しいとか、魔改造に伴うバッドノウハウが各社それぞれに蓄積されているような気がします。

この記事をきっかけに、認証システムの簡素化について思いを巡らせていただけると幸いです。
EMC最適化の多層基板設計における実践的アプローチ

<p>電子機器がますます普及する今日、電磁適合性（EMC）は多層<a href="https://www.pcbgogo.jp/pcb-landing.html" target="_blank">プリント基板</a>設計において解決しなければならない重要な課題となっています。電磁干渉（EMI）は、機器の性能に影響を与えるだけでなく、周囲の他の電子機器にも干渉を引き起こす可能性があります。ここでは、実際の設計経験を基に、EMC最適化の多層基板設計における実践的なアプローチを紹介し、PCBGOGOの技術的な優位性を見ていきましょう。</p>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4114843/64f018a3-248c-46de-920f-572eb5e459d3.jpeg" 
     alt="多層基板の設計図例 - EMC対策にも有効な構造" 
     width="600" 
     height="auto" 
     loading="lazy">
<h3>合理的な機能領域の区分け</h3>
<p>多層基板には多くの機能モジュールが集積されており、合理的に機能領域を区分けすることはEMC最適化の基本です。デジタル回路とアナログ回路を分けて配置し、デジタル信号の高周波ノイズがアナログ信号に干渉しないようにします。また、電力回路と信号回路を分けることで、電力回路の大電流が小信号回路に干渉しないようにします。</p>

<h3>接地設計の最適化</h3>
<p>良好な接地は電磁干渉を抑制するための重要な手段です。多点接地方式を採用し、高周波信号に対して低インピーダンスのループを提供します。一方、低周波信号には単点接地を用いることで、地ループ干渉を防ぎます。また、<a href="https://www.pcbgogo.jp/" target="_blank">プリント基板メーカー</a>のPCB-GOGOは、成熟した製造技術を駆使して、接地設計要件を正確に実現し、接地効果を保証します。</p>

<h3>信号伝送経路の制御</h3>
<p>信号伝送経路の設計はEMCに大きな影響を与えます。信号伝送線の長さを短縮し、信号の放射を減少させます。敏感な信号に対しては、グラウンドによるシールド処理を行い、外部干渉を遮断します。高速信号に関しては、インピーダンス整合設計を行い、信号反射による干渉を防ぎます。</p>

<h3>フィルタリングおよびシールド設計</h3>
<p>電源入力や信号入出力ポートにはフィルタ回路を追加することで、電磁干渉を効果的に抑制できます。適切なフィルタを使用して高周波ノイズを除去します。強い電磁波を発生させる部品や領域にはシールドケースを使用し、電磁干渉の拡散を防ぎます。</p>

<h3>部品配置と配線ルールの考慮</h3>
<p>部品配置が適切であれば、スペースを節約でき、信号伝送距離を短縮して干渉リスクを低減できます。配線時にはルールに従い、例えば平行配線や交差配線を避け、クロストークを防ぎます。</p>

<p>以上の実践的なアプローチにより、多層基板の電磁適合性を効果的に向上させることができます。<a href="https://www.pcbgogo.jp/" target="_blank">PCBGOGO</a>は、専門的な設計能力と高度な製造技術を駆使し、多層基板設計においてEMC最適化を徹底し、信頼性の高い製品を提供します。これにより、複雑な電磁環境下でも安定した動作が可能な電子機器の実現をサポートします。</p>
エンジニアのキャリアパス　〜王道３パターンとその先〜

こんにちは、元Yahoo!エンジニアで、現在は株式会社PRUMの代表をしている岩本です。  
今日は「エンジニアのキャリアパス」について、王道3パターンと、そこから広がる未来についてまとめてみました。

エンジニアを目指す人、今まさに現場で頑張っている人にとって、将来のイメージを持つことはとても大切です。  
でも同時に、「まずは目の前のことを全力でやる」ことが一番大事だという話も最後にしていますので、ぜひ最後まで読んでみてください！

---

## エンジニアキャリアの王道3パターン

まず、多くのエンジニアが歩んでいく道には、大きく3つのパターンがあります。

### ① ジェネラリスト

いわゆる「SE（システムエンジニア）」レベルの人たちを指します。  
要件定義も、設計も、プログラミングも、全部の工程を一通りこなせる人。

特徴としては、
- 特定分野に偏らず、バランスよく広い知識・経験を持っている
- 現場では“オールラウンダー”として重宝される
- 母数としては最も多く、経験を積んでいけば自然と目指していけるポジション

エンジニアとして最初に目指すキャリア像としても、とても現実的で安定しています。

### ② スペシャリスト

技術に特化して、とことん深堀りしていくタイプです。  
たとえば「フロントエンド特化」「インフラ特化」「AI特化」など、ある領域を極めていく道。

特徴としては、
- 深い専門知識と技術力が武器
- フルスタックエンジニアを目指す人もここに含まれる
- 希少性が高く、市場価値も高め

ただし、突き詰めるには継続的な学習と努力が必須なので、自然となれるわけではなく、強い意志が必要な道でもあります。

### ③ プロジェクトマネージャー（PM）

エンジニアは基本的に何かしらの「プロジェクト」の中で仕事をします。  
そのプロジェクトの進行管理やメンバーマネジメントを担うのがPMです。

特徴としては、
- 技術よりもプロジェクト進行がメイン
- メンバーやお客さんとのコミュニケーションが重要
- 自ら手を動かすよりも、人・スケジュール・課題を動かしていく

「エンジニアにはなったけれど、プログラミングはあまり好きじゃないかも」という人にも向いているポジションです。

---

## その先にある、たくさんのキャリア

キャリアは上の3つだけではありません。そこから派生して、さらに違う方向へ進んでいく人もたくさんいます。

### ① ITコンサルタント

プロジェクトマネージャーとの違いは「自ら提案から行う」点。  
PMは基本的に「受けた要件を遂行する」役割ですが、ITコンサルタントはクライアントに対して、
- 何を改善すべきか
- どんなシステムを作るべきか
といった上流部分から関わります。

ビジネスサイドとの距離が近くなり、結果的に年収帯も高くなりやすいキャリアです。
ただ、難しい！！！

### ② 他業種への転職

エンジニアを続けず、IT系の他企業へキャリアチェンジする人もいます。  
たとえば、SaaS企業のカスタマーサクセスや、プロダクトマネージャーへの転向など。

「エンジニアを辞める＝挫折」みたいに思われがちですが、そんなことは全然ありません。  
エンジニア経験がそれなりにあれば
- 技術理解がある
- システムや業務を深く考えられる
- ロジカルに様々なことを組み立てられる
といった強みがあり、IT業界では大きな武器になります。

---

## 最後に伝えたいこと

ここまでいろいろなキャリアパスを紹介してきましたが、  
**そもそもキャリアパスを考えるのは「一人前になってから」でいい**と思っています。

エンジニアの本質は、
- 求められていることをきちんと提供すること
- 任された仕事を責任を持ってやりきること

その繰り返しの中で、自然と自分の得意なことや、向いている道が見えてきます。

目の前のタスクを全力でやりきる。  
来たチャンスをしっかり掴む。  
その積み重ねの先に、きっと自分だけのキャリアが作られていきます。

焦らず、腐らず、目の前の一歩一歩を大切にしていきましょう！


---
PRUMのエンジニアの95%以上は、未経験からの採用です。
ぜひ、求人をチェックしてみてください！
▼ Wantedly求人
https://www.wantedly.com/projects/626662
▼ コーポレートサイト
https://prum.jp/
VISION 『日本で一番エンジニアが成長する会社を創る』
ご応募お待ちしておりますー！
ubuntu版 misskey アップデートコマンド メモ

自分用メモです。
以下の内容をターミナルに貼り付ければ終わりです。

こちらの内容をもとにインストールしています。

https://tech.kentem.jp/entry/2024/12/09/090000



```bash
sudo systemctl stop misskey
sudo su -s /bin/bash - misskey
cd /home/misskey/misskey
git pull;
NODE_ENV=production pnpm install --frozen-lockfile
pnpm run clean;
NODE_ENV=production pnpm run build;
pnpm run migrate;
exit
sudo apt update -y
sudo apt full-upgrade -y
sudo reboot
```

misskeyプロジェクトを応援しています。
ChatGPTを使用したアプリ開発記【シェアボタンの実装】

## ShareButton.jsの作成
```ShareButtons.js
import {
  FacebookShareButton,
  FacebookIcon,
  TwitterShareButton,
  LineShareButton,
  LineIcon,
} from "react-share";


// x-icon.svg はTwitterの新ロゴ「X」のSVGファイル。
// SVGファイルとは、Webで利用されるベクター形式の画像ファイル。
// ベクター形式:図形を数学的な式で表現するため、拡大縮小しても画質が劣化しない。﻿
import { ReactComponent as XIcon } from "./x-icon.svg"; 

const ShareButtons = ({ url, title }) => {
  return (
    <div className="flex gap-4 mt-4">
    
      <TwitterShareButton url={url} title={title}>
        <div className="w-8 h-8 rounded-full overflow-hidden bg-black flex items-center justify-center">
          <XIcon className="w-5 h-5 text-white" />
        </div>
      </TwitterShareButton>
      
      <FacebookShareButton url={url} quote={title}>
        <FacebookIcon size={32} round />
      </FacebookShareButton>
      
      <LineShareButton url={url} title={title}>
        <LineIcon size={32} round />
      </LineShareButton>
    </div>
  );
};

export default ShareButtons; // ✅ default export
```

## ホーム画面、プロフィール画面のコード
```Home.js
  const baseUrl = window.location.href; // ✅ 現在のページURL
  const title = "Keruma SNSで面白い投稿を見つけました！"; // ✅ 任意のタイトル

  <ShareButtons
      url={`${baseUrl}/post/${post.id}`}  // ← 投稿IDごとにシェア
      title={`Keruma SNSで面白い投稿を見つけました！「${post.text.slice(0, 30)}...」`}
  />

```

 ## UI

![スクリーンショット 2025-05-30 7.07.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1058366/b9c8cea7-2cfb-43a6-93b4-7feea3d2ab62.png)
laravel Socialite Socialite::driver('google')->user();の取得に使っているAPI

## 概要

laravelのSocialiteにて認証後のユーザー情報を取得する際に実行するAPIの実態を追う。

## 内容

Socialiteは下記のように記述するとユーザーの情報を取得できる。

```php
Socialite::driver('google')->user();
```

このときにどのようにしてユーザー情報を取得しているのかを簡単にまとめる。

`user()`の実装は下記にされている。

```vendor/laravel/socialite/src/Two/AbstractProvider.php
/**
 * {@inheritdoc}
 */
public function user()
{
    if ($this->user) {
        return $this->user;
    }

    if ($this->hasInvalidState()) {
        throw new InvalidStateException;
    }

    $response = $this->getAccessTokenResponse($this->getCode());
    $user = $this->getUserByToken(Arr::get($response, 'access_token'));

    return $this->userInstance($response, $user);
}
```

`getUserByToken()`を使ってユーザーの情報を取得しているぽい。同クラスに抽象メソッドの定義発見

```vendor/laravel/socialite/src/Two/AbstractProvider.php
/**
 * Get the raw user for the given access token.
 *
 * @param  string  $token
 * @return array
 */
abstract protected function getUserByToken($token);
```

今回はGoogleなので下記に実装（具象）がある。

```vendor/laravel/socialite/src/Two/GoogleProvider.php
/**
 * {@inheritdoc}
 */
protected function getUserByToken($token)
{
    $response = $this->getHttpClient()->get('https://www.googleapis.com/oauth2/v3/userinfo', [
        RequestOptions::QUERY => [
            'prettyPrint' => 'false',
        ],
        RequestOptions::HEADERS => [
            'Accept' => 'application/json',
            'Authorization' => 'Bearer '.$token,
        ],
    ]);

    return json_decode((string) $response->getBody(), true);
}
```

`https://www.googleapis.com/oauth2/v3/userinfo`にpostリクエスト送っている。
ということはOIDCで定義されているUserinfoのAPIにリクエストをなげているもよう