OmniAICreator/Qiita-1.07M huggingface dataset:
【図解】【初心者向け】TypeScriptの便利なユーティリティ型 - OmitとPickの違いを解説（1分で読める）

`TypeScript`のユーティリティ型である`Omit`と `Pick`の違いをめっちゃ簡単に解説します。

# `Pick<T, K>`
`Pick`はその名の通り、既存の型から指定したプロパティを **選び取って（Pick）** 、新しい型を作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620625/07b61cde-272b-43b1-bac2-4074166c3f78.png)

```typescript
// 元となる型
interface User {
  id: number;
  name: string;
  email: string;
  age: number;
}

// User型から 'id' と 'name' を選び取って新しい型を作成
type UserSummary = Pick<User, 'id' | 'name'>;

// 結果として、この型と同じになる
// interface UserSummary {
//   id: number;
//   name: string;
// }
```

# `Omit<T, K>`
`Omit`は `Pick` とは逆に、既存の型から指定したプロパティを **取り除いて（Omit）** 、その残り全てを使って新しい型を作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620625/7f977b01-03d0-4dec-acb2-18c95da036a9.png)

```typescript
// 元となる型
interface User {
  id: number;
  name: string;
  email: string;
  age: number;
}

// User型から 'email' を取り除いて新しい型を作成
type UserForPublic = Omit<User, 'email'>;

// 結果として、この型と同じになる
// interface UserForPublic {
//   id: number;
//   name: string;
//   age: number;
// }
```

# まとめ
`Pick` `Omit`を使いこなすことによって型の定義がDRY(Don't Repeat Yourself)になり、より安全で保守性の高いコードを書くことが出来ます。

「この型とこの型ほとんど同じだけど、一部のプロパティだけ違うなー」となったら`Pick` `Omit`を使ってみましょう。
Create In-App Prompts で　URLのエラー



# In the 'Customize Navigation in Console' prompt, we can’t find the Action Button URL set to 'https://help.salesforce.com/s/articleView?id=sf.console_lex_feature_parity.htm&type=5'.

+ [In the 'Customize Navigation in Console' prompt, we can’t find the Action Button URL set to 'https://help.salesforce.com/s/articleView?id=sf.console_lex_feature_parity.htm&type=5'.](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000TjLFc0AN)
+ [Error in Trailhead Challenge: Customize Navigation in Console – Action Button URL Issue](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000TjgSa)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/6b26674f-659c-4fdb-bf1b-0f6eaaaebe5b.png)


+ [Create Prompts in Lightning Experience issue](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000SXiCD)

:::note
The problem is the URL for the Spanish version of the Trailhead. 


English version URL (Correct):
https://help.salesforce.com/s/articleView?id=service.console_lex_feature_parity.htm&type=5

Spanish version URL: (Wrong)
https://help.salesforce.com/s/articleView?id=sf.console_lex_feature_parity.htm&type=5
:::
NuxtのSPAでGitHub Actionsを使った環境変数の管理方法

# はじめに

こんにちは、Gakken LEAP のバックエンドエンジニアの mizuno です。
今回、Nuxtで構築されたSPAのGitHub Actions設定をリファクタリングする機会がありました。

現在のプロジェクトのNuxtでは環境ごとの各変数をファイルに1つずつ書き出していたため、以下の課題がありました。

- 環境変数が増えるたびにGitHub Actionsの修正
- 設定値の一元管理ができない

本記事では、GitHub ActionsとNuxtの`runtimeConfig`を活用して、これらの課題を解決する方法を紹介します。

## 解決方法

### 1. Nuxt設定ファイルの準備

まず、`nuxt.config.ts`で環境変数を読み込む設定を行います。

```typescript:nuxt.config.ts
export default defineNuxtConfig({

  // 環境変数の設定
  runtimeConfig: {
    public: {
      apiBase: process.env.NUXT_PUBLIC_API_BASE,
      appName: process.env.NUXT_PUBLIC_APP_NAME,
      environment: process.env.NODE_ENV
    }
  }
})
```

### 2. 環境変数ファイルの作成

開発環境用の`.env`ファイルを作成します。

```bash:.env
NUXT_PUBLIC_API_BASE=http://localhost
NUXT_PUBLIC_APP_NAME=My Development App
NODE_ENV=development
```

### 3. GitHub Actionsワークフローの設定

GitHub Actionsのワークフローでは、buildステップのenvに環境変数を設定します。
ここに設定された値がビルド時にNuxtアプリケーションに注入され、本番環境用の設定として利用されます。

```yaml
- name: Setup Node.js
  uses: actions/setup-node@v4
  with:
    node-version: '22'

- name: Install dependencies
  run: npm ci

- name: Build
  run: npx nuxt generate
  env:
    NUXT_PUBLIC_API_BASE: ${{ vars.NUXT_PUBLIC_API_BASE }}
    NUXT_PUBLIC_APP_NAME: ${{ vars.NUXT_PUBLIC_APP_NAME }}
    NODE_ENV: production

- name: Deploy
  # デプロイ処理
  run: |
    echo "Deploying to production..."
```

### 4. アプリケーションでの環境変数の使用

コンポーネントやプラグインで環境変数を使用する方法：

```vue:components/AppHeader.vue
<template>
  <header>
    <h1>{{ appName }}</h1>
    <p>Environment: {{ environment }}</p>
  </header>
</template>

<script setup>
const config = useRuntimeConfig()

const appName = config.public.appName
const environment = config.public.environment
</script>
```

```ts:composables/useApi.ts
export const useApi = () => {
  const config = useRuntimeConfig()

  const apiCall = async (endpoint: string) => {
    const response = await fetch(`${config.public.apiBase}${endpoint}`)
    return response.json()
  }

  return {
    apiCall
  }
}
```

## GitHub Variablesの設定

1. GitHubリポジトリの「Settings」→「Secrets and variables」→「Actions」へ移動
2. 以下のVariablesを追加：
   - `NUXT_PUBLIC_API_BASE`: 本番環境のAPIベースURL
   - `NUXT_PUBLIC_APP_NAME`: 本番環境のアプリ名

## ポイントと注意事項

- SPAでは全てがクライアントサイドで実行されるため、秘匿情報は環境変数に含めないよう注意が必要です。
- 環境変数はビルド時に注入されるため、ランタイムでの変更はできません。

## まとめ

NuxtのSPAでの環境変数の扱いは、Next.jsと似ている部分もありますが、`runtimeConfig`を使用する点や`useRuntimeConfig()`でアクセスする点が異なります。

SPAでは全てがクライアントサイドで動作するため、セキュリティに注意しながら環境変数を設定することが重要です。

GitHub Actionsとの組み合わせにより、環境ごとに異なる設定を適用できるようになり、効率的なデプロイが可能になりました。

## エンジニア募集中

Gakken LEAP では教育をアップデートしていきたいエンジニアを絶賛大募集しています！！
ぜひお気軽にカジュアル面談へお越しください！！

https://gakken-leap.co.jp/recruit/
PostgreSQLでメンテ・実装・調査に役立つSQLフレーズ集

# はじめに

こんにちは、Gakken LEAP のエンジニアの shogawa です。
社内勉強会と称して、PostgreSQLの公式ドキュメントの読み合わせ会を開催しました。

参考：[公式ドキュメント](https://www.postgresql.jp/document/16/html/)

勉強会の内容から、**実務ですぐ使えそうなTips**をいくつか抜粋してご紹介します。

---

## 前提

* PostgreSQL 16
* pgAdmin 4（バージョン9.4）
* クエリを実行できる環境があること

---

## 目次

1. RETURNING \* で実行＆確認
2. テンポラリーテーブルで一時的な作業テーブル
3. SELECT ～ FOR UPDATE で排他ロック
4. pg\_stat\_activity で実行中クエリの確認と停止
5. EXPLAIN ANALYZE で実行計画の確認

---

## 1. RETURNING \* で実行＆確認

メンテナンス系のクエリ実行時、UPDATEした対象をあとから検索し直していませんか？
そんなとき便利なのが `RETURNING *`。**更新／削除したレコードをそのまま確認**できます。

```sql
UPDATE users
SET status = 'inactive'
WHERE last_login_at < NOW() - INTERVAL '1 year'
RETURNING *;
```

もちろん、手動メンテナンスが不要な仕組み作りが理想ですが、手元で確認するにはかなり有用です。

---

## 2. テンポラリーテーブルで一時的な作業テーブル

大規模メンテで、一時的な変換用テーブルやバックアップを作る場面、ありますよね？（あります）
そんなとき `table_yyyymmdd` みたいな名前で後に残るのは避けたいもの。
**テンポラリーテーブル**ならセッション終了と同時に自動で削除されます。

```sql
BEGIN;

CREATE TEMP TABLE tmp_users AS
SELECT * FROM users
WHERE plan = 'trial';

-- 一時的な作業をここで実施

COMMIT;
-- セッション終了と同時に tmp_users は自動で消えます
```

---

## 3. SELECT ～ FOR UPDATE で排他ロック

PostgreSQL のデフォルトのトランザクション分離レベル（[Read Committed](https://www.postgresql.jp/docs/16/transaction-iso.html)）では、
`BEGIN` しただけではまだ他のセッションの更新を防げません。つまり、クエリ実行時点で最新のデータが対象になります。

つまり以下のような競合が起こり得ます：

* セッションAが `SELECT` で処理対象を取得
* セッションBがその対象を先に更新
* セッションAが `UPDATE` しようとしても既に対象外になっている

これを防ぐには、**`SELECT ～ FOR UPDATE` を使ってロックを取る**のが有効です。

```sql
BEGIN;

SELECT id, status
FROM tasks
WHERE status = 'pending'
ORDER BY created_at
LIMIT 1
FOR UPDATE;

-- 取得したレコードを処理対象とみなし、後続UPDATE
UPDATE tasks
SET status = 'processing'
WHERE id = 123;

COMMIT;
```

---

## 4. pg\_stat\_activity で実行中クエリの確認と停止

大量件数を誤って検索し、クエリが返ってこない……あるあるですね。
そんなときには `pg_stat_activity` で実行中のクエリ状況を確認して、**キャンセル or 停止**します。

```sql
-- 実行中のクエリを確認
SELECT pid, usename, state, query_start, query
FROM pg_stat_activity
WHERE state != 'idle'
ORDER BY query_start ASC;
```

### クエリをキャンセル（接続は維持）

```sql
SELECT pg_cancel_backend(<pid>);
```

### クエリを強制終了（セッション切断）

```sql
SELECT pg_terminate_backend(<pid>);
```

> `pg_terminate_backend` はトランザクションもロールバックされるので注意！

---

### 💡 pgAdmin で止めるには？

* クエリエディタ上部の「■」ボタンでキャンセル（`pg_cancel_backend` 相当）
* **Terminate** は GUI からはできないため、SQL 実行が必要です

---

⚠️ 他人のセッションを止めるにはスーパーユーザー権限が必要です
⚠️ 誤って業務用プロセスを止めるとシステムに影響が出るので慎重に！

---

## 5. EXPLAIN ANALYZE で実行計画の確認

クエリがやたら遅い……。そんなときは実行計画の確認が定番です。

```sql
EXPLAIN ANALYZE
SELECT * FROM orders
WHERE created_at > NOW() - INTERVAL '7 days';
```

* `EXPLAIN` だけだと**予測コスト**
* `EXPLAIN ANALYZE` だと**実際の実行時間も含めた結果**

pgAdminではクエリエディタ上部の `Explain Analyze` ボタンを押すと、**グラフィカルに表示される**ため非常に便利です。

<!-- キャプチャを貼る場所 -->
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3455950/5decc53a-1b74-432a-89ec-5ab2d04fcbd7.png)

> 太い矢印が負荷の大きい処理箇所を示してくれるので、ボトルネックが見やすいですね！

---

## エンジニア募集中

メンバーが自発的に勉強会も開催したりする Gakken LEAP では
教育をアップデートしていきたいエンジニアを絶賛大募集しています！！

https://gakken-leap.co.jp/recruit/
AWS JumpStart 2025 に参加して得た学び

# 1. はじめに

「AWS JumpStart 2025」という、AWS初学者向けのイベントの案内を頂き、私自身は自称中級者くらいではあるものの、以下の目的で参加してみました。

- 「初心者向けにハンズオンを企画してください」などの依頼があり、初心者向けにはどういう学習コンテンツを提供すればよいか知りたい
- 参加者同士でのアーキテクチャ検討の時間があり、説明やQ&Aなどのコミュニケーションの訓練になりそう

丸々2日間の長丁場なのですが、学びが多く有益だったと思い、他の人にもお薦めしたいと思い、内容（＋自分の所感）を紹介したいと思います。

# 2. AWS JumpStart とは

AWS公式の案内サイトはこちらです。↓

https://aws.amazon.com/jp/blogs/news/aws-jumpstart-2025/

事前学習、講義、ハンズオン、参加者間でのアーキテクチャ検討、と盛りだくさんの内容になっています。
数年前から継続して行われていて、2025年は4回開催されるようです。（私は2025/5の回に初参加しました）

ひとつ前の 2025/3 の会に参加された方のレポートもいくつかあり↓、言いたいことはほとんどそちらに書いてあったのですが、改めて私も自分の所感も含めてまとめてみます。

https://qiita.com/morimune/items/ae60599bf81cadd79305

https://qiita.com/sousuke_neo/items/008a1269fff7eeb43569


# 3. イベントの様子

## ハンズオン
1日目の午後に行われ、VPC、ELB、ECSなどをマネコンから作成し、ECS上にブラウザで動作するメモ帳アプリをデプロイし、さらにAWSリソースの障害時の動作（Auroraの系切り替えなど）を確認する内容でした。

ちゃちゃっと終わらせて、残りの時間は会社の通常業務をしようとしていたのですが、グループワーク（モブプログラミング形式で、3名で10分交替でマネコン操作を実施）だったため、内職はできませんでした。ただ、交替で操作をやる中で、「Auroraって２台立てても普段書き込めるのは片方だけなんですよね」とかえらそうに説明したりすることができました。

また、ハンズオンではよくあることですが、特にECSの設定画面が手順書と最新のマネコンでだいぶ異なっており、「この値はこれのことですよね？」とかみんなで確認しながら進めたりして、一緒に構築している感がありました。

## アーキテクチャ検討
2日目の午後に行われ、仮想の企業のエンジニアになったという前提で、社長からの「こんなシステムを作ってほしい」という要求に応えられるシステムアーキテクチャを検討する内容でした。前日のハンズオンとはまた別メンバーでのグループワークで、各々がMiro上にお絵描きした構成図を元に説明、Q&A、全員の内容をマージなどして、グループとしての構成図を作成しました。

私も自分が作成した構成図に対して、「なぜECSをプライベートサブネットに展開するのですか？パブリックではだめなのですか？」など他の方から質問頂き、「いやなんとなくそのほうがセキュリティ的にベストプラクティスぽいかなと、、」などと回答したりしたのですが、こういう質問に堂々と的確に回答できるようにしなければと思いました。

優秀例として発表されたチームのアーキテクチャはすごく気合が入っていて、明らかに素人が作成した感じではないものもありましたが、我々のもの（以下に添付）も、それなりのものができたと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/76277d52-4105-4261-b03b-cfb94dcc181f.png)


## その他
オンラインでのイベントのため、以下のツールが活用されていました。
- Zoom：　講義、主催者からの説明
- Discord：　グループ単位でのディスカッション用のボイスチャンネル、AI(Claude？)やAWSソリューションアーキテクトの方への質問用のチャンネル
- Miro：　アーキテクチャ検討時のお絵描き用

Discordは、とりあえず聞いてみたいことはAIチャネルに聞いてみて、それでも分からなければAWSソリューションアーキテクトの方に質問するなど、内容に応じて使い分けることができました。Miroには既にAWSアイコンなどが用意されていて、すぐに構成図を書き始めることができました。

参加者は700～800名程度いたのですが、その人数分のDiscordグループやMiroボードが事前に作成されており、スムーズにグループワークを行うことができ、これだけの人数を問題なくさばくのも運営がすばらしいなと思いました。

# 4. 最後に
本イベントは初学者向けとなっており、事前の学習教材を見て臨めばOKとなっていますが、さすがに完全に初学者だと大変で、ある程度触った経験があり、ちょっと慣れてきた1～2年目のエンジニアくらいがちょうどよいのかなと感じました。講義含めた学習内容も充実していることに加え、知らない人と一緒に設定したり、アーキテクチャ検討するのが特に良い経験になるかなと思いました。次回開催時(2025/8予定)に、該当のメンバーに参加してもらい、感想を聞いてみたいと思います。

また、当初の参加目的だった「初学者向けにはどんな内容を提供すればよいか？」についてもヒントを得ることができました。今回のような大規模な研修を自分で開催するのは難しいですが、コンテンツは参考にできそうと思いました。
【Git Hub Copilot】プランとモデル簡単まとめ

## はじめに
こんにちは、エンジニア4年目の嶋田です。  
本記事では **GitHub Copilot** の料金プランと利用可能モデルを **5 分で把握** できるよう整理してみました。

## 目次
- [個人向けプラン早見表](#個人向けプラン早見表)
- [プラン別モデル対応表](#プラン別モデル対応表)
- [Premium リクエストとは？](#premium-リクエストとは)
- [法人向けプラン概要](#法人向けプラン概要)
- [プラン選択ガイド](#プラン選択ガイド)
- [まとめ](#まとめ)
- [最後に](#最後に)


## 個人向けプラン早見表

| プラン | 価格 (月額) | コード補完上限 | Premium リクエスト枠* | 含まれる主要モデル | 追加モデル購入 |
|-------|-------------|---------------|-----------------------|-------------------|----------------|
| **Free** | ¥0 | 2,000 回 | 50 回 | GPT-3.5 | 不可 |
| **Pro** | $10 / ¥1,600 目安 | 無制限 | 300 回 | GPT-4.1 / GPT-4o | $0.04/req |
| **Pro+** | $39 / ¥6,200 目安 | 無制限 | 1,500 回 | すべての提供モデル (GPT-4.5 preview など) | $0.04/req |

> ** Premium リクエストは **「上位モデル (GPT-4.5 preview など) の利用、Agent Mode 実行」** で消費される高コスト枠です。Pro/Pro+では **GPT-4.1 / GPT-4o での通常チャットは消費ゼロ** なので注意を！

---

## プラン別モデル対応表

| モデル | Free | Pro | Pro+ |
|--------|------|-----|------|
| GPT-3.5 | ● | ● | ● |
| GPT-4.1 | ● | ● | ● |
| GPT-4o  | ● | ● | ● |
| GPT-4.5 (preview) | － | － | ● |
| Claude / Gemini / o 系 | △＊ | △＊ | ● |

＊Free / Pro ではモデルごとに利用可否やPremium リクエスト消費の条件が異なります。Pro+ は枠内なら消費せずフルアクセス

## Premium リクエストとは？

- **定義**：高負荷 API 呼び出し（上位モデル推論・Agent Mode など）1 回 = 1 Premium。  
- **消費ルール**  
  - Free: すべての Chat / Agent が 1 Premium 消費。  
  - 有料: GPT-4.1 / GPT-4o は消費ゼロ。**それ以上のモデル使用時のみ減算**。  
- **追加購入**：枠超過後は **$0.04 / req** で従量課金。

## 法人向けプラン概要

| プラン | 補完 | Premium | 主な違い |
|--------|------|---------|---------|
| **Business** | 無制限 | 300 / 月 | SAML SSO, 使用状況レポート |  
| **Enterprise** | 無制限 | 1,000 / 月 | 監査ログ, モデルポリシー設定 |  |


## プラン選択ガイド

| あなたの状況 | おすすめ |
|--------------|----------|
| まず試したい | **Free** : LLM 補完体験を掴むには十分 |
| GPT-4 水準で常用したい | **Pro** : Unlimited 補完 + GPT-4.x 標準使用可 |
| 複数モデルを駆使 & Agent を酷使 | **Pro+** : 全モデル+広い Premium 枠で安心 |
| チームで統合管理 | **Business / Enterprise** : SSO や監査が必須なら |

---

## まとめ

- **Free → Pro → Pro+** の順に  
  1. **補完上限**が 2,000 → 無制限  
  2. **使えるモデル**が GPT-3.5 → GPT-4.1/4o → 全モデル  
  3. **Premium リクエスト枠**が増量  
- Pro 以上なら **通常開発は Premium 無消費**。  
- モデルを切り替えて最適レスポンスを探れるのは **Pro+ から**。  

## 最後に
自分のためにもまとめてみました。
誰かのお役に立てれば幸いです。
ssh_config に設定したルールをコマンドライン起動にも適用したい

おぉ、できるんだと思ったのでメモ。

こんな感じでワイルドカードの Host 指定してる際に、

```text:~/.ssh/config
Host bastion
    HostName xxx.xxx.xxx.xxx
    User ec2-user
    IdentityFile ~/.ssh/bastion.pem

Host internal-*
    User ec2-user
    IdentityFile ~/.ssh/internal.pem
    ProxyJump bastion

Host internal-a
    HostName aaa.aaa.aaa.aaa

Host internal-b
    HostName bbb.bbb.bbb.bbb
```


コマンドラインから ssh 叩くときにも `internal-*` のルールに引っかかってほしいとき、

こんな感じで指定するといけるらしい。

```bash
$ ssh -o Hostname=ccc.ccc.ccc.ccc internal-c
```
ブラウザサンドボックス：概念、説明、使用方法

```markdown
# ブラウザサンドボックス：概念、説明、使用方法

## 🛡 サンドボックスとは？
サンドボックスとは、潜在的に危険なコードやアプリケーションを安全な仮想環境に隔離し、システムへの被害を防ぐためのセキュリティ手法です。

例えるなら、子どもたちが安全に遊べる「砂場」のようなもので、外部との接触を制限しつつ、自由に活動できる空間を提供します。

---

## 🌐 ブラウザサンドボックスの仕組み

### ローカルブラウザ分離
- ユーザーの端末上で仮想ブラウザを実行
- 悪意あるコードの影響を仮想環境内に限定

### リモートブラウザ分離
- ブラウザ処理をクラウドサーバーで実行
- ローカル端末にはDOMのミラーや映像ストリームのみを転送
- 実行例: VDI + ストリーミング型表示

---

## ✅ サンドボックスの利点

- ローカルOS・デバイスを保護
- ゼロデイ攻撃の影響を最小化
- 信頼できないコードの事前テストが可能
- 脅威の検疫と分析に役立つ
- ハイブリッド（ローカル＋クラウド）構成が可能
- 他のセキュリティツールとの併用で強固な防御層に

---

## 🔍 サンドボックス化される主な資産

| 資産カテゴリ | 内容 |
|--------------|------|
| ウェブブラウザ | Chrome, Firefoxなど、外部リソースにアクセスするアプリ |
| ブラウザプラグイン | Javaなど、外部コンテンツを読み込む拡張機能 |
| ウェブページ | JavaScriptで制限されたロジック |
| モバイルアプリ | AndroidやiOSでのアプリ実行環境 |
| Windowsアプリ | UACを通じた権限管理と制限実行 |

---

## 🧱 サンドボックスの種類

1. **アプリケーションサンドボックス**  
   信頼できないアプリを隔離して実行

2. **ブラウザサンドボックス**  
   悪意あるスクリプトからローカル資源を保護

3. **セキュリティサンドボックス**  
   添付ファイルや不審なサイトを分析・隔離

---

## 🧪 各ブラウザのサンドボックス実装

### Chrome / Edge
- Broker（親プロセス）とTarget（子プロセス）に分離
- Targetは隔離された環境でのみ実行

### Firefox
- Sandboxingレベルを0〜2で設定可能  
  `about:config` > `security.sandbox.*` を検索

---

## ⚠ サンドボックスは100%安全？

- 一部コンポーネント（Flash, ActiveXなど）は外部へアクセス可能
- サンドボックスは「安全を強化」するが、「完全な防御」ではない

---

## 🏁 まとめ

サンドボックスは、未知の脅威やゼロデイ攻撃に備えたセキュアな隔離環境を提供する重要な技術です。  
開発・テスト環境としても有効で、クラウドベースのリモートブラウザ分離と組み合わせることで、より高いセキュリティ水準が実現できます。

---
```
生天目佳高Tips：Python＋Pandasで簡単データ分析：マーケター向け実例付き


はじめに
フリーランスSEとしてスタートアップ支援をしていると、「売上データを分析したいけどExcelでは限界がある」という相談をよく受けます。今回は、PythonとPandasを使って、非エンジニアでも実践できるデータ分析手法を紹介します。

対象読者
マーケター、営業担当者
Excel分析に限界を感じている方
Python初心者
実例：ECサイトの売上分析
実際のスタートアップ支援案件で使用した分析例を紹介します。

データの準備
python
import pandas as pd
import matplotlib.pyplot as plt

# CSVファイルの読み込み
df = pd.read_csv('sales_data.csv')

# データの概要確認
print(df.head())
print(df.info())
基本的な分析
python
# 月別売上集計
monthly_sales = df.groupby('purchase_month')['amount'].sum()
print(monthly_sales)

# 商品カテゴリ別分析
category_analysis = df.groupby('category').agg({
    'amount': ['sum', 'mean', 'count']
}).round(2)

print(category_analysis)
顧客分析（RFM分析の簡易版）
python
# 顧客別購入回数と平均購入額
customer_analysis = df.groupby('customer_id').agg({
    'amount': ['sum', 'mean', 'count'],
    'purchase_date': 'max'
}).round(2)

# 上位顧客の抽出
top_customers = customer_analysis.nlargest(10, ('amount', 'sum'))
print(top_customers)
データ可視化
python
import matplotlib.pyplot as plt
plt.rcParams['font.family'] = 'DejaVu Sans'

# 月別売上推移
monthly_sales.plot(kind='line', figsize=(10, 6))
plt.title('Monthly Sales Trend')
plt.xlabel('Month')
plt.ylabel('Sales Amount')
plt.show()

# カテゴリ別売上比較
category_sales = df.groupby('category')['amount'].sum()
category_sales.plot(kind='bar', figsize=(10, 6))
plt.title('Sales by Category')
plt.xticks(rotation=45)
plt.show()
実務での活用ポイント
1. データクレンジングを怠らない
python
# 欠損値の確認と処理
print(df.isnull().sum())
df = df.dropna()  # または df.fillna(0)
2. 期間比較分析
python
# 前年同月比較
df['year_month'] = pd.to_datetime(df['purchase_date']).dt.to_period('M')
yoy_growth = df.groupby('year_month')['amount'].sum().pct_change(periods=12)
まとめ
PythonとPandasを使うことで、Excelでは困難な大量データの分析が簡単にできます。特にスタートアップでは、迅速な意思決定のためのデータ分析が重要です。

今回紹介したコードは、実際の案件で効果を実証済みです。ぜひ業務で活用してみてください。

環境情報
Python 3.9+
pandas 1.5+
matplotlib 3.5+
Razorとは？初心者でもわかるASP.NETのビューエンジン入門

## はじめに

ASP.NET や Blazor でフロントエンド開発を行っている方であれば、Razor という名前を一度は耳にしたことがありますよね？
Razor は C# のコードと HTML を組み合わせて記述できる **テンプレートエンジン**。  
本記事では、次の疑問に答えながら Razor の基本から実用テクニックを解説する。
あまり覚えることも少ないし、一回書いてしまえばあとは応用効くので、構えずに読んでみてください。

- Razor で何ができるのか  
- `@` 記号の役割は何か  
- 部品化（部分ビュー）はどう行うのか  

---

## Razor とは？

Razor は Microsoft が開発した **軽量なビューエンジン** です。C# でロジックを記述しながら、HTML と組み合わせて Web ページを生成できる。

| 特徴 | 説明 |
| ---- | ---- |
| `@` 記号で C# を埋め込める | HTML 内にシームレスに C# を挿入できる |
| 拡張子 `.cshtml` / `.razor` | ASP.NET MVC は `.cshtml`、Blazor は `.razor` を使用 |
| IntelliSense 対応 | Visual Studio / VS Code で補完が効く |
| SEO に強い | サーバーサイドレンダリングのためクローラーに認識されやすい |

---

## 基本の構文

```razor
@{
    var title = "Razor 入門";
}
<h1>@title</h1>
```

### 条件分岐

```razor
@if (Model.IsLogin)
{
    <p>ようこそ、@Model.UserName さん</p>
}
else
{
    <p>ログインしてください。</p>
}
```

### ループ処理

```razor
@foreach (var item in Model.Items)
{
    <li>@item.Name</li>
}
```

### コメントの書き方

```razor
@* これは Razor のコメントです *@
```

---

## コンポーネント・部分ビューの活用

Razor ではビューの共通化や再利用を目的として **部分ビュー** や **Razor コンポーネント** を使用できる。

### 部分ビューの例（ASP.NET MVC）

```razor
@Html.Partial("_UserProfile", Model.User)
```

### Blazor の Razor コンポーネント例

```razor
<!-- ProfileCard.razor -->
<h3>@User.Name</h3>
<p>@User.Bio</p>
```

```razor
<!-- 親コンポーネント -->
<ProfileCard User="@user" />
```

---

## よくある落とし穴

| 事象 | 原因と対策 |
| ---- | ---------- |
| `@` 記号がそのまま表示される | `@@` と書くと `@` 文字が出力されるため注意 |
| HTML タグ構造が崩れる | `if` や `foreach` 内のタグ閉じ忘れに注意 |
| 名前の衝突 | ViewModel、ViewBag、ローカル変数で同名を避ける |

---

## まとめ

Razor は ASP.NET アプリケーションにおける重要な技術要素。

- C# と HTML を自然に混在できる
- サーバーサイドレンダリングにより SEO に強い  
- 再利用性の高い UI 設計が可能

Blazor や ASP.NET Core MVC を学習する際には、Razor の理解が必須。  
Razor構文慣れたら使いやすいので、がんばって習得してください。
三項演算子で長くなりがちなので、適宜if文とかで分岐したほうが見やすい場合もあります。
@で呼び出す変数とかは初期値入ってないとよく落ちるので、イニシャライズ処理ちゃんとしてくださいね～。
TSの鬼 第2回：numberとstringから“型の世界”は始まる

## はじめに
前回

https://qiita.com/mukai3/items/044269903848d3a5183f

TypeScriptに入門するうえで、最初に出会うのが「基本の型」である。
特に `number` や `string` といったプリミティブ型は、あらゆるデータ構造の土台として機能する。

この記事では、TypeScriptの基本型について、JavaScriptとの違いや設計上の意味を丁寧に解説する。

---

## 基本の型とは？

TypeScriptでは、主に次のような基本型が存在する。

| 型名                   | 説明                 |
| -------------------- | ------------------ |
| `number`             | 数値全般（整数・小数）        |
| `string`             | 文字列                |
| `boolean`            | 真偽値（true/false）    |
| `null` / `undefined` | 空値・未定義（オプショナル型で使用） |
| `symbol`             | 一意な識別子（高度な用途）      |
| `bigint`             | 任意精度の整数（2⁵³以上の数）   |

JavaScriptではこれらを自由に使えるが、TypeScriptでは **「変数にどの型が入るかを宣言」** することで、
プログラムの意図を明示できる。

---

## 型アノテーションの基本

変数や関数の引数に型を指定するには「`:`（コロン）」を使う。

```ts
let age: number = 28;
let name: string = "Yuki";
let isAdmin: boolean = false;
```

型推論も効くが、明示することで **「どう使ってほしいか」** を読み手に伝えることができる。

---

## 関数への型指定

```ts
function greet(name: string): string {
  return "Hello, " + name;
}
```

このように、引数・戻り値の型を明示することで、
「この関数は文字列を受け取り、文字列を返す」と一目で分かるようになる。

これは**コードが“自己説明的”になる**という大きな利点である。

---

## `any`との違いを体感する

```ts
let value: any = "hello";
value = 123;
value = false;
```

`any`は“なんでもあり”の型であり、TypeScriptの恩恵をすべて無効化してしまう。
一方で、`string`や`number`を指定すると、**「型が違うと怒られる」**。
この怒られこそが、**意図しないバグを防ぐ武器**なのである。

---

## 型は“型安全”の起点である

基本型を使いこなすとは、単にエラーを減らすことではない。

* 引数の意味を明確にする
* チームの他の開発者に意図を伝える
* 関数の正しさをコード上で保証する

このように、**型は設計思想そのものである。**
その意味で、`number` や `string` は最小単位の「設計材料」とも言える。

---

## まとめ：型の基礎を甘く見ない

TypeScriptを学ぶとき、派手な型構造やジェネリクスに目が行きがちだが、
**最もよく使われるのは `number` と `string` である。**

これらの型に正しく意味を持たせられるエンジニアこそが、
上級者にふさわしい“型の鬼”への第一歩を踏み出すことになる。

---

## 次回予告

『TSの鬼 第3回：配列・オブジェクト・ユニオン型を制す』

次回は型を組み合わせることで、より複雑なデータ構造を表現する技術へ進んでいく。
【個人開発ログ】ITなんでも調査屋（仮）part2 個人開発

# はじめに
私が鋭意、個人開発中である 「ITなんでも調査屋（仮）」 というWebサイトについて、
制作の過程を、やりたいこと → どう実装したか　と言う感じでまとめます。
https://everyit.net/ （調査依頼だけできるようになっています！）

# この記事でわかること
個人開発の過程が見られます。
「やりたいこと」と「実装したこと」をそれぞれ記していきます。

# 動作環境・使用するツールや言語
- VSCode
- React ＋ Typescript
- AWS Amplify Github 連携でのホスティング
- AWS AppSync - DynamoDB

# 背景を作りたい
## 問題点
背景が白だとやはり、淡白で作りかけみたいな印象がありました。
## 実装内容
元々探偵を意識しまくっているので、「探偵事務所の壁」を意識、かつWebサイトとして見やすさを損なわないようにしたかったです。調べたところ探偵ものの時代では、濃い色＋薄い色の縦縞の壁紙が流行していたようで、一旦、茶色/ベージュの細い縦縞を試しましたが、背景が派手すぎてページのコンテンツより目立ってしまいました。
結果としてはもっとコントラスト小さくして穏やかな色調にし、縦縞の感覚を広げることで、背景の主張が強すぎないようにしました。
![スクリーンショット 2025-06-20 9.16.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4097028/2a77c62f-1f6e-4c35-a758-ab7236a79926.png)

# About画面の調整
## 問題点
- そもそも骨組みだけで、デザインがなかった
- 文章ががダラダラ長かった
- 即ブラウザバックしたくなるようなだささ
## 実装内容
壁紙を決めることができたので、「看板風」にしました。
![スクリーンショット 2025-06-20 9.14.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4097028/c4a6e048-4c92-4ee3-a6c1-ef22d61fb9ab.png)


# 依頼ボードの調整
## 問題点
ボードっぽくなかった。

## 実装内容
壁紙が出来たことで、その壁紙に掛けるコルクボードという構図にしやすいと思いました。
コルク風CSSをAIに作成してもらい実装。コルクボードの上にピンで依頼書を止めているいい感じの構図に近くなりました。
![スクリーンショット 2025-06-20 9.15.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4097028/e4dfa531-e96a-4011-ba75-07a6eb78e8ad.png)


# 次回予告？
- 依頼時の管理者通知機能
- 認証機能（ログインし、調査結果を記入する機能）
- 依頼ボードの絞り込み機能

認証機能を作成した段階で、一旦プロフィールに記載などしたいです。
XR Interaction ToolkitではじめようQuestアプリ開発

## 1. はじめに

Meta Quest 3の登場により、Mixed Reality（MR）アプリケーション開発は新たな段階に入りました。高解像度パススルー機能により、一台のデバイスでVRとARの両方の体験を提供したり、開発したりできる環境が整ったのです。

QuestアプリをUnityで開発するにはMeta社が提供するMeta XR SDKを使う方法と、Unity社が提供するXR Interaction Toolkitを使う方法があります。これまで、Meta XR SDKを用いた開発手順を紹介する[記事](https://qiita.com/Tks_Yoshinaga/items/32bfe7567abbb2ac9521)を公開してきました。  
そこで今回は**XR Interaction Toolkit**を用いた開発手順に注目した解説記事を書いてみることにしました。

本連載の位置づけとしては、初心者がXR Interaction Toolkitで提供されているプレハブやスクリプトの使い方を段階的に学習できるチュートリアルを目指しています。トピック毎に記事を分け、特定の機能を実現するための最小構成を学べる資料になるように構成しています。

## 2. 連載目次

### 基本編

- [XR Interaction Toolkitのインストールとプロジェクトの設定](https://qiita.com/Tks_Yoshinaga/items/26ab2f342be44f7b8661)
- [MetaQuestでオブジェクトをVR表示（XRI版）](https://qiita.com/Tks_Yoshinaga/items/47d1cc29250879cff214)
- [MetaQuestのパススルー機能を使ったAR表示（XRI版）](https://qiita.com/Tks_Yoshinaga/items/9afb32731f457caabb67)
- [MetaQuestのロコモーションをオフにする（XRI版）](https://qiita.com/Tks_Yoshinaga/items/71b3c4f369b790ad098b)

### インタラクション編

- [MetaQuestでオブジェクトマニピュレーション（XRI版）](https://qiita.com/Tks_Yoshinaga/items/6ccbfbb3940da79e520a)
- [ボタンを例にしたUnityのUI操作（XRI版）](https://qiita.com/Tks_Yoshinaga/items/d27570cd338cef31ea27)

<br><br>  

記事の間違いのご指摘や、修正のご提案、勉強してみたい内容などがあればぜひご連絡ください。  
X(旧Twitter): https://twitter.com/Taka_Yoshinaga


## 3. 対象読者

本連載は以下のような方を対象としています：

- **Unity初級〜中級者**：Unityの基本操作は理解している
- **XR開発初心者**：VR/AR開発に興味があるが経験は少ない
- **Meta XR SDK経験者**：XR Interaction Toolkitへの移行を検討している
- **Quest開発初心者**：Meta Questでのアプリ開発を始めたい


## 4. GitHub

本記事で作成したサンプルはGitHubでも公開しています。

[GitHub](https://github.com/TakashiYoshinaga/MetaXR-SDK-Samples)のXRI_Samplesプロジェクトを活用してください。

各チュートリアルに対応するサンプルシーンが含まれているため、動作確認や学習の参考にご活用ください。
MetaQuestのロコモーションをオフにする（XRI版）


## 0. 本記事の内容

本連載で使用している<b>XR Origin Hands (XR Rig)</b>には手やコントローラを使ったインタラクションに関する基本的な設定が済んでいるオブジェクトが内包されています。これらの機能の中にはジョイスティックを使ったテレポートや視点の回転を行うロコモーション（Locomotion）も提供されていて、デフォルトで使用可能な状態になっています。

しかしコンテンツによっては（特にARコンテンツでは）このような機能が不要な場合もあります。本記事では、**XR Interaction Toolkit**を使用した不要なロコモーション機能を無効化する設定方法について紹介します。

なおVRやARを実現するための基本的な設定は済んでいることを前提に解説を行います。VRやAR開発の基本設定についてご興味がある方は下記の記事もあわせてお読みください。

**[VR版]**

[MetaQuestでオブジェクトを表示（XRI版）](https://qiita.com/Tks_Yoshinaga/items/47d1cc29250879cff214)

**[AR版]**

[MetaQuestのパススルーを使ったAR表示（XRI版）](https://qiita.com/Tks_Yoshinaga/items/9afb32731f457caabb67)

## 1. ロコモーション機能の無効化

**[Locomotionオブジェクトの無効化]**

- Hierarchyで<b>XR Origin Hands (XR Rig)</b>を見つける
- 子要素の**Locomotion**オブジェクトを非アクティブ化

**[左手コントローラーのテレポートオブジェクトの非表示]**

- Hierarchyで<b>XR Origin Hands (XR Rig)</b>を見つける
- **Camera Offset -> Left Controller**の順に子要素を開く
- **Left Controller**のInspectorで**Controller Input Action Manager**を見つける
- **Teleport Interactor**から<b>Teleport Interactor (XR Ray Interactor)</b>を削除
- **Left Controller**の子要素の**Teleport Interactor**オブジェクトを非アクティブ化

**[右手コントローラーのテレポートオブジェクトの非表示]**

- Hierarchyで<b>XR Origin Hands (XR Rig)</b>を見つける
- **Camera Offset -> Right Controller**の順に子要素を開く
- **Right Controller**のInspectorで**Controller Input Action Manager**を見つける
- **Teleport Interactor**から<b>Teleport Interactor (XR Ray Interactor)</b>を削除
- **Right Controller**の子要素の**Teleport Interactor**オブジェクトを非アクティブ化

## 2. 無効化される機能

以上の設定により、以下のロコモーション機能が無効化されます：

| 機能 | 説明 | 対象コンテンツ |
|------|------|----------------|
| **テレポート** | ジョイスティックでの瞬間移動 | VR/AR共通 |
| **視点回転** | ジョイスティックでの視点の左右回転 | 主にVR |
| **連続移動** | ジョイスティックでの連続的な移動 | 主にVR |

これらの機能は特にARアプリケーションでは現実空間との整合性を保つために無効化することが推奨されます。

## 3. 次のステップ

ここまでの内容でロコモーション機能の無効化が完了しました。次はオブジェクトのマニピュレーション機能の準備について解説します。

[MetaQuestでオブジェクトマニピュレーション（XRI版）](https://qiita.com/Tks_Yoshinaga/items/6ccbfbb3940da79e520a)

## 4. XR Interaction Toolkitに関する記事一覧はこちら

[XR Interaction ToolkitではじめようQuestアプリ開発](https://qiita.com/Tks_Yoshinaga/items/9e691eb679fff982a1c9)
Google Workspace（GWS）導入の最初の一歩 #1

## はじめに
Google Workspace（グーグル ワークスペース）は、Google の提供するグループウェア
として利用可能な組織向けオンライン アプリケーション セットです。以下の３つの特徴
を持つとともに、高度なセキュリティと 99.9% の稼働率が保証されたクラウドコンピュ
ーティング サービスとなります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3104221/4a672e60-e803-4e7e-b469-2c17dc6c722b.png)

本記事では、3回にわたりGoogle Workspacee（以下、GWS）導入に必要な手順をお伝え
していきます。ご参考となれば幸いです。

## 目次
1. 記事の対象者
2. 動作環境
3. 導入手順
　- 全体の流れ
　- 導入準備
　- DNS設定
　- GWS設定
　- メールのセキュリティ対策
4. おわりに
5. 参考サイト

## 記事の対象者
- GWS導入を検討している方
- GWS導入で最初にすべきことを知りたい方

## 動作環境
本記事では、2025年5月時点の以下サービスを使用しています
　- GWS
　- お名前.com（ドメインサービス、DNSサービス）
※ドメインとは、インターネット上の住所のようなもので、Webサイトやメール
 アドレスを特定するために使われます。例えば、「example.com」のような文字列が
 ドメイン名です。
 ※DNSとは、ドメイン名 (例: google.com) とIPアドレス (例: 172.217.160.142)
 を変換するシステムのことです。人間が覚えやすいドメイン名でインターネット上の
 サイトにアクセスできるように、DNSサーバがIPアドレスを調べて対応させています。﻿

## 導入手順
### 全体の流れ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3104221/00649680-33f6-4a95-b9e3-3d676df43379.png)

### 導入準備
  大きく以下の３つのことを確認、準備しておきます。
  ・システム環境イメージ（GWS/お名前.comをどう設定するかを決めておきます）
  ・運用体制（Googleなど各種サービス提供者からの連絡先などを決めておきます）
  ・決済手段（GWSなどの利用料をどこで負担するかなどを決めておきます）
#### システム環境イメージ
・使用したいドメイン（候補を３つくらい）
・GWSで使用したいサービス（メール、表計算、会議、スライド、Webページなど）
#### 運用体制
・ドメイン/DNS管理者（お名前.comでのユーザ登録に必要）
・GWS管理者（GWS初期設定に必要）
#### 決済手段
本記事では、GWSとお名前.comを使用している為、GWSとお名前.comへの利用料決済が
必要となります。
基本クレジットカードでの決済となりますので、ご使用するクレジットカードをご準備
ください。


--
ここまでで、準備は完了です。いかがだったでしょうか？
準備はおろそかになりがちですが、今後の設定作業をスムーズに行っていくためには
大切な作業です。上記を参考に、しっかりご準備ください。

いよいよ、本格的な設定手順となります。お楽しみに。

次回：Google Workspace（GWS）導入の最初の一歩 #2 「DNS設定」

---
本記事に関するお問い合わせは、こちらまで。
メールアドレス：sys@agri-dx.jp
電話番号：080-3156-5221
ライフプランシミュレーターをReact(Vite)+TypeScript+PythonでWEBアプリ化したい！

## はじめに

**「自分の家計、本当にこれで安心だろうか？」**

この問いは、多くの人にとって“漠然とした不安”として心の奥に残っているものだと思います。私自身もその一人でした。積立NISAやiDeCo、保険や住宅ローンなど、一応それらしい制度には乗っているつもり。でも、定年後の生活費や突発的な支出を想定した“構造的な計算”をしたことがあるかと言われると、答えは「NO」でした。

業務でPower BIやPythonを使うようになり、データの力を感じるようになっていた中、「自分の人生もデータで可視化できないか？」という発想に至ったのが始まりです。個人向けの家計アプリやファイナンシャルプランナーが使うようなテンプレートではなく、“自分自身のデータ”を用いて“自分に最適化された構造”で未来を描いてみたい。そんな動機からライフプランシミュレーターの自作に取り組み始めました。

この記事では、Power BIによる初期分析、M言語による積立・運用ロジック構築から始まり、React + TypeScript によるWebアプリのモックアップ開発、そしてVercel上での試験公開までのプロセスを記録しています。あくまでこれは試作段階であり、現時点では固定データによる可視化調整とUI構成の検証が目的です。最終的な構想としては、Pythonバックエンドによる動的計算処理とGoogleスプレッドシート連携による入出力の自動化を想定したWEBアプリに仕上げていきたいなと考えています。

## Power BIでの第一歩：制度を構造化する

最初に取り掛かったのは、Power BIによる分析ダッシュボードの構築でした。家計の可視化というと「円グラフ」や「月次の出費分析」が思い浮かびますが、私の関心は「年次の資産推移」と「制度による資産制約の影響」を見極めることにありました。

そのため、以下のような年次ベースのデータテーブルをPower Query（M言語）で整備していきました：

- 年齢テーブル
- 収支テーブル
- 積立設定テーブル
- 積立記録テーブル（再帰処理）
- 運用結果テーブル（利回りの年次変化対応）

特に積立記録テーブルでは、年間上限、停止年齢、元本累積、iDeCoとNISAで異なるルールといった複雑な制度条件をすべてM言語で条件分岐・ループ処理しながら実装しており、実際の制度とかなり整合性の高い挙動を再現できています。

この構造は、単なるビジュアルだけでなく、制度理解の深化に非常に役立ちました。

## 可視化とモックアップの狙い

Power BIでは以下のようなグラフとテーブルを作成しました：

- 折れ線グラフ：現金・NISA・iDeCoの資産推移
- KPIカード：資産寿命（枯渇年）、最終年残高
- テーブル：年齢・収支・積立・評価額の詳細

**開発してみたPowerBIレポート**
![スクリーンショット 2025-06-20 081311.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4080640/20de6cd9-eeaa-4c22-aac2-fc78ccd5d501.png)


しかし、Power BIはアプリとして配布したり、都度の更新を気軽にするにはやや敷居が高く、ファイル共有やライセンス制限が足かせになります。そのため、UI設計と可視化の手触りを試す意味で、React + TypeScript によるモックアップを作成しました。

## Webアプリモックアップの技術構成と実装状況

現時点の実装は以下の構成です：

- React + TypeScript
- Recharts（グラフ）
- Tailwind CSS（デザイン）
- Vercel（ホスティング）

もうプログラムを勉強したのは遠い昔で、こんなモダンな環境構築をしたこともなかったので、Git＋Github⇒Vercelというデータ展開がこんなあっさりできちゃうのは驚きでした！

またRechart.jsやTailwind CSSという非常にリッチなライブラリが無料で手に入るとめちゃくちゃ開発スピードが加速することもあり、UI設計でモチベーションがもりもり上がってきました。

**開発中画面**
![スクリーンショット 2025-06-20 081745.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4080640/82513805-f45e-4aa8-978f-733281b8d0ee.png)


## 今後の構想と課題：M言語からPythonへ

現在の計算処理はPower Query（M言語）で構築されており、非常に強力な反面、Webアプリとの連携は難しいです。今後の構想としては：

- M言語で構築したロジックをPythonに完全移植
- pandasとNumPyを用いた積立元本の再帰ロジック再構築
- StreamlitやFastAPIによるAPI実装で、バックエンド処理として動的計算
- Googleスプレッドシートからの読込・書き出しを gspread や pygsheets で接続

などを考えています。

M言語とPythonで大きく異なるのは、**評価タイミング**と**メモリモデル**です。Power Queryはステップ単位で明確な依存関係を持ち、再帰処理も関数型的に組めます。一方でPythonでは逐次実行モデルを前提にしているため、ループや状態遷移を明示的に定義する必要があり、変数の扱いやデータ構造の設計思想が変わってきます。

その変換をどうスムーズに行うか、テーブル設計とロジック設計を再整理する必要があります。

## 今後

今後は

- 評価コメントをChatGPTに生成させて結果表示する
- 入力系の設計(質問形式でなるべく入力工数の高さを感じさせない作りに)
- ビジュアルの改良(堅いテーマなのでカジュアル・ポップな感じに)

といった部分を中心としながら、先に書いた開発のキモである「計算処理を担当するバックエンドをPythonで処理する」というところの作りこみに着手していきたいと思ってます。

ある程度形になったらQiitaで公開します！
【パンダ本トラブルシュート】Kali LinuxでVPN接続できない

## 目的
ハッキングを2時間で始める本　を読んでいる。
VPN接続でつまづいたので記録に残しておく。

## 環境
Windows11　Home
x64
VirtualBox内

## 状況
KaliLinux上でtryhackmeにアクセスし、（ユーザー名）.ovpnをダウンロード。
パンダ本の通りciphers AES-256-CBCをdata-ciphers AES-256-CBCに書き換え。
ターミナルでOpenVPNコマンド実行してVPN接続しようとしたが、いくら待っても「～Completed」が出てこない
エラーでもなく、途中で止まっている感じ。

## 解決策
実は繋がっていた。
Initialization　Sequence Comletedの後にさらに行が表示され、Protocol options: exclipt-exit-notify 3　で終わっていた。
これで終わっても繋がっている模様。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/353370/2a97e96c-e3cc-41a8-ac16-8594b1412af9.png)


## コマンドラインではない接続方法
こちらを参考に、KaliLinuxの操作画面からでもVPN接続できました。
コマンドラインでつなぐの大変だなと思っていたので感謝。

https://qiita.com/gadagizi/items/eaa8c7a44e66a09711e5
足りないパッケージをインストールメディアからインストールする

# はじめに
この記事を見ているっていうことは、自分と同じく「スタンドアロン環境でサーバ構築」しようとしているかなーと思います。

OSのディスクイメージをDLする際、dvd版とminimal版が存在します。
（一旦細かいことは置いておいて）上記2つの違いとして「最初からインストールされているパッケージ量の違い」が挙げられます。

リポジトリサーバを環境内に作っていない場合、このやり方は使うんじゃないかなーと思うので、参考になれば幸いなり。


# 背景・目的
 - スタンドアロン環境でLinuxサーバにパッケージをインストールしたい
 - あるのはOS媒体のみ！
 - minimal版で足りないパッケージがいろいろあるよー
 - OS媒体を使って、ローカルリポジトリを建てよう！

# 環境
 - OS：AlmaLinux 8.4

# 実装・手順

## ステップ1：まずはDVD版媒体をそうぬー
読んで字のごとく。
とりあえず、マシンに媒体をぶちこむのだ。

## ステップ2：媒体のマウント
マウントをしましょう。
マウント先は/mediaで大丈夫なハズ。
デバイスファイルはほかに何も挿入していなければ、たぶん/dev/sr0だと思う。
```
mount -r /dev/sr0 /media
```

マウント出来たら、中身がのぞけるようになっているか確認しよう。
```
ll /media
```

電源オン/オフが多いと、毎回マウントするのは面倒くさいから、/etc/fstabに書いて自動マウントしちゃうようにしてもいいとは思うけど、これはお好みかな。
```
vi /etc/fstab

～viエディタが開いたら、最下行に↓エントリを追加～
/dev/sr0 /media iso9660 ro,auto,nofail 0 0
```

## ステップ3：リポジトリファイルの作成
リポジトリファイルってなんぞ・・・っていう方はググってねー
これがないと、パッケージ管理ツール（yum,dnf）がパッケージを見つけられない（表現あってるのか？）ので、作らなきゃダメっす。

まずは、原本をコピって所定のディレクトリにリポジトリファイルを置いてみよう。
```
cp /media/media.repo /etc/yum.repos.d
```

配置が完了したら、使えるように編集しましょ。
```
vi /etc/yum.repos.d/media.repo

～viエディタが開いたら、以下のように編集する～
[InstallMedia-BaseOS]
name=InstallMedia-BaseOS
mediaid=None
metadata_expire=1
gpgcheck=1
cost=500
baseurl=file:///media/BaseOS
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-Almalinux

[InstallMedia-AppStream]
name=InstallMedia-AppStream
mediaid=None
metadata_expire=1
gpgcheck=1
cost=500
baseurl=file:///media/AppStream
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-Almalinu
～EOF～

※media.repoファイルは上記記述だけあれば、一旦おｋ

保存して終了
```

## ステップ4：GPGキーのインポート
まだあるっす。
このままでインストールしようとするとGPGエラーが発生するため、GPG KEYのインポートが必要です。
・・・メンドイかもだけど、いちお下記説明を読んでみてね。

	**GPG署名について**
	GPGとは・・・
	正式名称は「GNU Privacy Guard」といい、Linux環境では自分が意図した作成者が作ったソフトであるか、使うインストーラーが本物であることを検証（身元が正しいかどうか）してからインストールします。このとき、ソフトウェアが検証に使用される仕組みの一つがGPGです。
	GPGは暗号化ソフトウェアであり、暗号化だけでなく署名や認証といったオンライン上の機密や信用を管理するツールとして使用されます。
	特徴として、公開鍵暗号方式を使用しますが、その鍵の管理のために認証局を設置しません。各利用者の責任でカギを管理し、取得した公開鍵をチェックします。
	署名は署名でも、カギに対する署名とファイルに対する署名の二種類があるため、注意が必要です。

ほぇ～～・・・（おれもよくわからん）


インストールメディアからパッケージをインストールする際、どうやらGPG KEYは既に所持している状態であるため、取り出す（インポートする）ことによってGPGチェックをPASSできるみたい。
難しいことはさておき、要はこんな感じと解釈↓。

	このパッケージ、本当に大丈夫なやつ？
	↓
	え！？証明できるカギないやん！
	↓
	ほんじゃ、インストールさせるわけにはいかんな～（ニヤニヤ）
	↓
	（懐にしまってあるカギを取り出す）
	↓
	ｳｪｧｯ!?もっとるやんけ・・・最初からだしーな・・・
	↓
	インストールしますか？[Y/n]

・・・あってるかわかんないけど、もりおはこんな感じに解釈した。
外部のパッケージをインストールする際はまた新たなカギが必要であると思うけど、そもそもこのGPGチェック自体は回避も可能。（できるんかい）
「鍵なんか知るか、あほぅ！！」という方はインストールする際、以下の方法を使ってみてくださいまし。
```
dnf install --nogpgcheck <パッケージ名>
```
たしか、これで良いはず・・・

良い子のみんなはちゃんと以下のコマンドを実行して、鍵を用意してからインストールしような？おじさんとの約束だぞ！
```
rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-AlmaLinux
```

## ステップ5：おまじない
ここまで出来れば、もうパッケージインストールはできる状態だと思いますが、念のため確認作業を～

```
dnf repolist 
```

上記コマンド実行した標準出力に以下の内容が出てくればおｋ。

	===============================================================
	
	repo id                        repo name
	InstallMedia-AppStream         InstallMedia-AppStream　
	InstallMedia-BaseOS            InstallMedia-BaseOS　　 
	
	===============================================================

あとは最後にこれも置いておくね。

```
dnf clean all
```

ここまで来れば、いい子も悪い子もパッケージインストールできるようになってるハズ・・・！！


完

# 最後に
簡単な手順でもQiitaに出すの大変・・・
なんとか試行錯誤しながら、効率化していかないとな～。。。

引き続き頑張っていくぜ。
学習16日目

# 今日学んだこと
① validationのlengthオプション
② 変数の中身の存在による条件分岐

## ① validationのlengthオプション
文字列の長さの上限や下限を指定する時に用いる。
例えばカラムの型をstringにした場合、256文字以上のデータを保存しようとするとエラーになってしまう。
そこで、予めバリデーションで制限をかけておく。
(例)
```
validates :name,  length: {maximum: 50 }
```
上記では、51文字以上の文字を入力して保存しようとすると、バリデーションに引っかかる。

## ② 変数の中身の存在による条件分岐
例えばツイートの一覧表示画面で、何もツイートされていない時には「まだツイートはありません」と表示させたい場合に用いる。
(例)
```
<% if @tweets.present? %>
 (ツイートがある時に表示させたい記述)
<% else %>
 (ツイートがない時に表示させたい記述)
<% end %>
```

# 感想
オリジナルアプリでは最終的に文字数の下限と上限を設定したいので、独自にバリデーションを定義してから用いる必要がありそうだと感じた。
(多分Railsのモデルにおいて、上限と下限を両方設定することはデフォルトだとできないはず)
IBM i 7.6 がPowerVSで利用可能に（発表から約2か月+で）

大阪21 (OSA21)で確認しました。

IBM i 7.6の発表2025/4/8 →　出荷開始（ダウンロード開始）が4/18　→　自分で確認できたのは4/20前後だったと思いますので約2か月前後で利用可能になったという事でよいかなと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011394/f7edeb86-4298-43f5-b824-f16a0b430871.png)

利用可能までの大まかなスケジュール感のメモ書きとして。
【Day18】インスタ用のキャプションを生成する（後編）

## はじめに

勉強とアウトプットを兼ねて、Webアプリ開発の記録を記事にしてみます。

個人のメモ的な側面が強いです。
Web開発初心者すぎて至らぬところだらけだと思いますが、暖かい目で見ていただければ幸いです。

↓ これまでの内容 ↓
[【Day0】アプリが完成するまで毎日投稿](https://qiita.com/midorigame/items/f9b9a445c945b4a837b1)
[【Day1】開発環境を考える](https://qiita.com/midorigame/items/e26344599e2ffaa22033)
[【Day2】開発環境を構築する、、、はずでした](https://qiita.com/midorigame/items/3f57f2691a8e1074adb8)
[【Day3】まずはフロントだけ開発環境を構築する](https://qiita.com/midorigame/items/9de27ba72aaef504a833)
[【Day4】バックエンドの開発環境を整えつつ、マルチコンテナ対応のDevcontainerにする](https://qiita.com/midorigame/items/5b95374cd85f715a6498)
[【Day5】お試し実装！ファイルをアップロードしてバックエンドで処理する](https://qiita.com/midorigame/items/9663f0063b95b501c08a)
[【Day6】Docker Desktopが起動しなくなり泣きながら原因調査する](https://qiita.com/midorigame/items/d07df1caf05267d0609d)
[【Day7】画像にフレームとExif情報を付けてみる](https://qiita.com/midorigame/items/e2d85ce8dd7a5bcb5daf)
[【Day8】フロントに表示する画像のサイズを小さくする](https://qiita.com/midorigame/items/f7f5f9b14fb79259c716)
[【Day9】フロントエンドとバックエンドをそれぞれデプロイする](https://qiita.com/midorigame/items/4c8037024e667ff1105b)
[【Day10】結局コンテナ1つで開発する方が楽かもしれない](https://qiita.com/midorigame/items/60b484b2007c3aab474b)
[【Day11】アプリが一通り完成！！](https://qiita.com/midorigame/items/38ddccc09f0625aaebd6)
[【Day12】FastAPIのコードをリファクタリングする](https://qiita.com/midorigame/items/72ed91ff9add5504fab9)
[【Day13】機能実装！フレームに記載するExif情報を編集できるようにする（前編）](https://qiita.com/midorigame/items/790b0fcd54620f9fb573)
[【Day14】ReactのリファクタリングとUI変更を同時にやった](https://qiita.com/midorigame/items/b492ae717e59fb137b70)
[【Day15】機能実装！フレームに記載するExif情報を編集できるようにする（後編）](https://qiita.com/midorigame/items/9a649aa2a0a17d1db552)
[【Day16】インスタ用のキャプションを生成する（前編）](https://qiita.com/midorigame/items/4aa9bf4f1d05180436db)
[【Day17】インスタ用のキャプションを生成する（中編）](https://qiita.com/midorigame/items/af8f705595c1d26e7c4a)

## 前回やったこと

Webアプリの新機能として、インスタ投稿用のキャプションの自動生成を実装中です。

フロントにキャプション表示エリアを作成する
↓
キャプション用のテキスト（定数）をレスポンスとして返却するAPIを作成する

というように段階的に実装していきました。

## 今回やったこと

アップロードした画像のExif情報から自動的にキャプションを生成する部分を実装しました！
これでアップロード→自動生成→表示の一連の流れができました。

キャプションをどういう内容にするかはこれからも考えていきたいですが、今はとりあえずカメラとレンズのハッシュタグにしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307348/ca49956b-791d-45c0-bb9d-b333c9f5bc6c.png)

特にレンズにはスラッシュやピリオドなどが含まれることが多いですが、これらがあるとハッシュタグとして機能しなくなるため取り除く処理を加えています。（実際にインスタで調べてみてもそういう風なハッシュタグにしている）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307348/315fb21c-54a0-48de-953a-f234231c4d6e.png)


## 気づいたこと、学び

今回は行きあたりばったりで実装を分割しながら進めていきましたが、最初にこの順番で進めよう！って計画を立ててから臨めるとより良かったですね。
タスクを分解してどうやって進めていくか、これは実業務でも大事なこと、、、！

## おわりに

3日かけて新しい機能を実装しました！
次はこの機能のまだまだな部分を探して改善しつつ、自動テストなどのCI/CD周りを拡充させていければと思っています。
闘魂Phoenix道場：MySQLをDockerで立ち上げるッ！！！ Phoenixアプリから使わせていただく

いよいよはじまりました！
[Qiita Tech Festa](https://qiita.com/tech-festa/2025) :tada::tada::tada: 

https://qiita.com/tech-festa/2025


# はじめに

こんにちは、ElixirとPhoenixをこよなく愛する闘魂プログラマーです。  
つまりAIプログラマーです。あっ、AIとは、**A**ntonio **I**nokiさん、つまり猪木さんのことです。  

本記事は、[【あなたの】はじめてのMySQL](https://qiita.com/official-events/10a25cbc18d0f3e2ddb0) への参加記事です。


https://qiita.com/official-events/10a25cbc18d0f3e2ddb0

次の２つの「はじめて」で書きます。

- MySQLをメインテーマにすえた記事を**はじめて**書く
- Phoenixアプリが使用するデータベースとしてMySQLを**はじめて**使う

もしかしたら、以前も書いたことあるかも :interrobang: ですし、やったことあるかも  :interrobang: です。あしからずご了承ください。覚えていないので、**新鮮な気持ちで「はじめて」やります！**

# PhoenixのデフォルトDBはPostgreSQL

PhoenixのデフォルトDBはPostgreSQLです。そのことについては次の記事にしたためました。

[闘魂Phoenix道場：PostgreSQLをDockerで立ち上げるッ！！！（devcontainer付き） Phoenixアプリから使わせていただく](https://qiita.com/torifukukaiou/items/bc1e3486330e1be2674f)

https://qiita.com/torifukukaiou/items/bc1e3486330e1be2674f

この記事では、MySQLを使ってみたいと思います :qiitan:
私は学生や社会人にAWSを教える機会があります。その際に、Webアプリケーションの例としてWordPressを取り上げます。ですから、いつもMySQLにはお世話になっています。余談でした。

# Phoenixアプリが使用するデータベースにMySQLを採用する

_見出しが何だか、上から目線です。MySQL愛好家のみなさまごめんなさい :pray::pray::pray:_ 


[Phoenix](https://www.phoenixframework.org/) のプロジェクトを作成する際に、使用するデータベースについて何も指定しないとPostgreSQLがデフォルトで選ばれます。

今回は、MySQLを選びます。自発的に、MySQLを選ぶわけです。

```bash
mix phx.new hello --database mysql
```

`--database mysql`で、MySQLを指定するという格好です。
ドキュメントは、「[mix phx.new - Options](https://hexdocs.pm/phoenix/Mix.Tasks.Phx.New.html#module-options)」です。

話の順番が前後しますが、[Phoenix](https://www.phoenixframework.org/)とは、Elixir製の**すんごいWebアプリケーションフレームワーク**のことです。

# DockerでMySQLを立ち上げる

新しいPCを新調するたびに、自分のローカルにMySQLを入れるのは面倒ですし、慎重派の私はDockerコンテナで立ち上げています。

```bash
docker run -d --rm -p 3306:3306 \
  -e MYSQL_ALLOW_EMPTY_PASSWORD=yes \
  -e MYSQL_ROOT_PASSWORD= \
  mysql
```

## バージョン

2025/06/20現在、バージョンを指定しないと、「9.3.0 MySQL Community Server - GPL」が立ち上がっていました。   

## 環境変数

`MYSQL_ALLOW_EMPTY_PASSWORD`と`MYSQL_ROOT_PASSWORD`には、`config/dev.exs`にデータベースへの接続情報が以下のようにデフォルトで作られるのでそれにあわせています。「[mysql - Environment Variables](https://hub.docker.com/_/mysql)」の記述をChatGPTの協力のもと読み込んで環境変数をセットしました。  


```elixir:config/dev.exs
config :hello, Hello.Repo,
  username: "root",
  password: "",
  hostname: "localhost",
  database: "hello_dev",
  stacktrace: true,
  show_sensitive_data_on_connection_error: true,
  pool_size: 10
```

## CRUDを試す

`mix phx.gen.live Accounts User users name:string age:integer`とやって、指示通りに、`lib/hello_web/router.ex`を編集し、`mix ecto.migrate`（マイグレーション）してから簡単なCRUD（Create/Read/Update/Delete）操作を試してみました。**もちろん、動きます！** 
  
[mix phx.gen.live](https://hexdocs.pm/phoenix/Mix.Tasks.Phx.Gen.Live.html)タスクについては、リンク先をご参照ください。簡単にざっくり言うと、データモデル、スキーマ、マイグレーションファイル、GUIをいい感じに作ってくれる足場をかためるコマンドです。

# おわりに

Phoenixアプリが使用するデータベースにMySQLを**はじめて**使ってみました。
もしかしたら、以前も書いたことあるかも :interrobang: ですし、やったことあるかも  :interrobang: です。あしからずご了承ください。覚えていないので、**新鮮な気持ちで「はじめて」やりました！**

[【あなたの】はじめてのMySQL](https://qiita.com/official-events/10a25cbc18d0f3e2ddb0)キャンペーンをきっかけに、Phoenixで組み合わせて使ってみようと思いました。  

闘魂とは、己に打ち克つこと。そしてPhoenixアプリケーションの裏にMySQLあり。

**元氣ですかーーーッ！！！**
Geminiでキツネと遊ぶ魔法少女を描いてみた。

# 概要

Geminiでキツネと遊ぶ魔法少女を描いてみました。

# 実装

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

```
水のキツネと遊ぶ魔法少女を描いてください。
```

![水のキツネと遊ぶ魔法少女_20250620.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192024/fa62a3c6-dede-4c1e-a8e7-2c3735fab0e9.png)

# まとめ

可愛い。何かの役に立てばと。
Databricksサイドメニューのアップデート

こちらのアップデートです。サイドメニューの構成が変更されました。

https://docs.databricks.com/aws/ja/release-notes/product/2025/june#jobs--pipelines-in-the-left-navigation-menu

> **左のナビゲーションメニューにおけるジョブとパイプライン**
> 左のナビゲーションの**ジョブとパイプライン**アイテムは、Databricksの統合データエンジニアリング機能であるLakeflowへのエントリーポイントです。左のナビゲーションにあった**パイプライン**と**ワークフロー**は削除され、それらの機能は**ジョブとパイプライン**から利用できるようになりました。

```mermaid
graph TD
    subgraph "変更後"
        A2[ナビゲーション]
        A2 --> B2[ジョブとパイプライン]
        A2 --> C2[その他の項目...]
        B2 --> E2[パイプライン機能]
        B2 --> F2[ワークフロー機能]
    end
    
    subgraph "変更前"
        A1[ナビゲーション]
        A1 --> B1[パイプライン]
        A1 --> C1[ワークフロー]
        A1 --> D1[その他の項目...]
    end

    B1 -.移動.-> E2
    C1 -.移動.-> F2
    
    style B1 fill:#ffcccc,stroke:#ff0000,stroke-width:2px,stroke-dasharray: 5 5
    style C1 fill:#ffcccc,stroke:#ff0000,stroke-width:2px,stroke-dasharray: 5 5
    style B2 fill:#ccffcc,stroke:#00aa00,stroke-width:3px
```

**変更前**

![Screenshot 2025-06-20 at 5.59.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/c60c3556-3815-4c12-aada-a5cf1c08b5fb.png)

**変更後**

![Screenshot 2025-06-20 at 6.03.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/afa21b58-f717-43bc-9bcb-d869330e7787.png)

![Screenshot 2025-06-20 at 6.05.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/a5473afa-6c14-4d7a-b214-8f26088255e8.png)


### はじめてのDatabricks

[はじめてのDatabricks](https://qiita.com/taka_yayoi/items/8dc72d083edb879a5e5d)

### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)
shared_ptrで管理されたクラス内でthis(自身のshared_ptr)を扱いたいときの落とし穴

# はじめに
あなたはスマートポインタというものを知り、`shared_ptr`でクラスを管理することを試みます。また、今まで`this`で行っていたように、自身の`shared_ptr`を取得したいです。単純に`shared_ptr(this)`とするとエラーになってしまいます。インターネットで調べると、`enable_shared_from_this`というものを継承させればいいということを知ります。しかしこれは罠です。調べると色々出てくるので割愛しますが`enable_shared_from_this`には様々な問題があります。有識者に聞くと「`enable_shared_from_this`なんて使わないよ？」と言われ、じゃあ僕の設計が間違っているのか…？となります。（ここまで実体験）

この問題にはわかりやすく画期的な解決策があり、しかもそれはかなり著名なC++設計法として知られています。

__それは ズバリ`shared_ptr`をラップすることです。__

# 解決策
いまこういう状況です。
```cpp
class Player
{
public:
    void update(double dt)
    {
		/*
		いろんな処理
		*/

		//std::shared_ptr<Player> player = ... // update()内で自身の shared_ptr　がほしい。

		/*
		いろんな処理
		*/
	}
};
```
Playerのラッパークラスを作ります。

元のPlayerクラスを　➝　`PlayerDetail`
Playerのラッパークラスを　➝　`Player`
という風に命名します。


```cpp
//元のPlayerクラス
class PlayerDetail
{
public:
    void update(double dt)
    {
		/*
		いろんな処理
		*/

		//std::shared_ptr<PlayerDetail> player = ... // update()内で自身の shared_ptr　がほしい。

		/*
		いろんな処理
		*/
	}

};

//元のPlayerクラスのラッパー
class Player
{
public:
	Player() 
		:player(std::make_shared<PlayerDetail>()) // コンストラクタでshared_ptrを作成。
	{
	}

	void update(double dt)
	{
		player->update(dt);//ラッパークラスでもupdate()を定義し、中でPlayerDetailのupdate()を呼びます
	}
private:
	std::shared_ptr<PlayerDetail> player;//shared_ptrをラップしている。
};

```

まだラッパークラスを作成しただけでなんの解決にもなっていません。
そこで、`PlayerDetail`のupdate()に`shared_ptr<PlayerDetail>`の引数を追加し、ラッパークラスでupdate()を呼び出す際に渡してあげます。

```cpp
//元のPlayerクラス
class PlayerDetail
{
public:
	void update(const std::shared_ptr<PlayerDetail>& player, double dt)
	{
		/*
		いろんな処理
		*/

		// 自身の shared_ptr である player が使える！！！

		/*
		いろんな処理
		*/
	}

};

//元のPlayerクラスのラッパー
class Player
{
public:
	Player()
		:player(std::make_shared<PlayerDetail>())
	{
	}

	void update(double dt)
	{
		player->update(player, dt);//playerを渡してあげる
	}
private:
	std::shared_ptr<PlayerDetail> player;
};
```

なんということでしょう。問題が解決しました！

update()以外のメンバ関数でも使いたい場合は、その都度引数に`std::shared_ptr<PlayerDetail>`を持たせ、ラッパークラスから渡してあげます。
メンバ関数を増やしたら、その都度ラッパークラスのメンバ関数も増やさないといけないのは少し手間ですが、そこは目をつぶりましょう。

ラッパークラスを作ると

```cpp
std::vector<std::shared_ptr<Player>> players;
```
こうやって書いてたのが
```cpp
std::vector<Player> players;
```
こうでよくなったりするなど、多くの場面でいちいち`shared_ptr`と書かなくて良くなり、型の見た目もスッキリするという効果もあります。

# 実は
このような実装は「pImplイディオム」として知られています。pImplイディオムについては他の記事を調べてください。何故かどの記事でも自身のshared_ptrを渡せることについて全く言及していませんが、それを抜きにしても様々なメリットがあるようです。

```diff_cpp
private:
-    std::shared_ptr<PlayerDetail> player;
+	std::shared_ptr<PlayerDetail> pImpl;
```
今回は`player`として持たせていましたが、`pImpl`と命名するとpImplイディオムであることが分かりやすくなり、他者からの可読性向上が見込めます。
(初心者向け)Rubyでじゃんけんする #1

# 開発環境

エディター / 実行環境
GuthubCodeSpaces (https://github.co.jp/features/codespaces)
※特に動作環境に縛りはありません。

Rubyのインストールは終わっているものとして進めます。
Rubyがインストールされているかわからないなら、ターミナルやコマンドプロンプト(Windows)で、以下のコマンドを実行し、エラーが出なければインストールされています
```
ruby -v
```
# 作るものの流れ
1, プレイヤーがじゃんけんで出す手をプログラムに入力する
2, CPUがランダムに出す手を決める
3, CPUとプレイヤーの出した手を判定し、勝ち、負け、あいこを判定する
4, 結果を出力する

# 1, プレイヤーがじゃんけんで出す手をプログラムに入力
Rubyでプログラムに何かを渡すには、実行する時に引数を渡すことで実現できます。例えば、
```ruby
Ruby main.rb Test Test2
#(このコードは例ですので、実行できません。)
```
のように、main.rbを実行する際にTestという引数(オプション)と、Test2という引数(オプション)を設定することができます。
では、プログラム側でこの引数を受け取るにはどうするかというと、ARGV[]という配列を使えば引数を幾つでも取得できます。
<details><summary>配列の使い方</summary>

## 配列の使い方
### 配列の定義
```ruby
list = []
```
これでlistという名前の、何も入っていない配列とを定義できます。
また、
```ruby
list2 = [0,1,2,3,4,5,6,7,8,9]
```
とすれば、0から9の数字が入っているlist2という名前の配列を定義することができます。配列の中に入るのは数字とは限りませんので、
```ruby
list3 = ["a","b","c","d"]
```
のように文字の配列を定義することもできます。
### 配列の取得
配列を取得するには、 リスト名[インデックス] とします。具体的には、
```ruby
list[0]
#このプログラムは例ですので、動作しません。
```
のようにすると、listという名前のリストの1番目を取得できます。
なぜ1番目の取得に1ではなく0を用いるのかというと、プログラミングでは、インデックスは0から始めるという決まりがあるからです。言語によって変わりますが、大体の言語は0で始めます。
そのため、
```ruby
list = [0,1,2]
puts list[3]
```
を実行しても、何も出力されません。これは、listの4番目を取得しようとしているけどlistには3番目までしか定義されていないため、4番目には何も存在しないからです。

配列の追加や削除に関しては、今回は使わないので割愛します。

</details>

### プログラムに渡された引数を取得する

今回のプログラムでは、プレイヤーの出す手だけを引数とした渡せば良いので、
```ruby
player = ARGV[0]
```
とすれば、playerという変数にプログラムに渡された1つ目の引数を代入できます。

ここで一度、正常に渡されているか確認しましょう。以下のプログラムをCodeSpacesに入力して、ターミナルで以下のコマンドを実行してください。

:::note warn
※main.rbのところは、自身の作ったファイルに置き換えてください
:::

```ruby:main.rb
player = ARGV[0]
puts player
```
```txt:ターミナル
Ruby main.rb "Test"
```
うまく実行されたでしょうか、実行できたら、ターミナルに、Testと表示されているはずです。Testを他の文字列に変えると、出力も変わりますが、""で囲うのを忘れないでください。

# 2,CPUがランダムに出す手を決める
Rubyには、配列の中からランダムに一つ取り出すという便利な関数が標準で存在します。それをうまく利用して、CPUにランダムな手を選ばせましょう。
### 出す手の定義
まずは、CPUが出すことのできる手を配列で管理します。Main.rbを以下のように更新してください。
```ruby:main.rb
player = ARGV[0] #プレイヤーの手を取得
cpu = ["グー","チョキ","パー"] #出すことのできる手を定義
cpu_hand = cpu.sample #今回出す手を決める
```
Rubyでは、
```ruby
list.sample
#(このコードは例ですので、実行できません。)
```
と記述すると、listからランダムに一つ取り出すことができます。今回のコードだと、グー、チョキ、パーの3つからランダムに取り出すという動作になります。ここで、本当にランダムに取り出されているのかを検証しましょう。
```ruby
cpu = ["グー","チョキ","パー"] #出すことのできる手を定義
cpu_hand = cpu.sample #今回出す手を決める
puts cpu_hand
```
これを実行すると、実行するたびにグー、チョキ、パーのどれかが出力されるはずです。