OmniAICreator/Qiita-1.07M huggingface dataset:
要件変更で炎上しない！インフラPMOが見たプロジェクト成功の分かれ道

こんにちは。現在、インフラ領域でPMOを担当しているtomoya_1998です。
これまで複数のプロジェクトに関わってきた中で、「これはうまく回るな」「これはしんどいな…」と感じる場面が度々ありました。

今回はそうした経験をもとに、**スムーズに進むプロジェクトと、停滞しがちなプロジェクトの違い**を3つに整理してみました。
特にインフラ系PJでは、こうした部分が整っていないと、後から大きなトラブルにつながることも多いと感じております。

## ① 要件変更への対応フローが整っているか
✅ 良いPJ：
　構成変更やセキュリティ要件の見直しが発生した際、確認 → 調査 → レビュー → 承認といった事前に決められたフローで処理される

❌ 悪いPJ：
　「あれもやって欲しい」「あとで伝えます」などが日常化し、構成変更の履歴や合意が残らない

📌 インフラは“後戻りが難しい”からこそ、変更対応の流れを整えておくことが重要です。
設計変更は避けられませんが、**適切なフローがあれば、混乱や手戻りを最小限に抑えること**ができます。

# ② 各領域に“管理専任”の担当がいるか
✅ 良いPJ：
　サーバー、ネットワーク、DBなどの各領域に、作業実務とは別に進捗・課題・情報整理を担う管理担当（チーム内のPMO的なポジション）が配置されている

❌ 悪いPJ：
　すべてのやり取りや管理がチームリーダーに集中しており、情報が整理されず、進捗把握・課題管理が属人的になっている

📌 作業と管理が同一人物だと、どうしても抜けや遅れが発生しやすい上、欲しい情報が降りてこないことも多いです。
📌 加えて、**見積段階で管理工数を役務に含めておく**ことが重要。
これを怠ると、後々現場が疲弊する要因にもなります。管理は“最初から設計するもの”です。

# ③ 重要なやり取りがテキストで残っているか
✅ 良いPJ：
　決定事項や依頼内容がチャット・議事録・メール・チケットなどで共有され、履歴が残っている

❌ 悪いPJ：
　「さっき電話で言ったんですけど」「○○さんに直接伝えました」など、口頭伝達が中心

📌 情報は “言った”だけでは共有にならず、“書いてある”ことで初めてチームの資産になります。言った・言わないを防ぐためにも、PJに関わる会話は、基本的に証跡として残しておきましょう。どこに残すかも明確になっていれば、尚良しだと思います。

# おわりに
今回挙げた3つのポイントは、いずれも派手さはないものの、プロジェクトを安定して進めるための土台になるものです。

PMOとして感じているのは、**プロジェクトは“管理の仕組み”で決まる**ということ。
「何となくうまくやる」では立ち行かなくなってきた今だからこそ、こうした構造的な視点を持つことが、ますます重要になってきていると感じます。

同じような課題意識を持っている方にとって、少しでも参考になれば幸いです。
一流のITエンジニアになるために｜今後の学習計画と進め方

こんにちは、ゆーりです。

今日から技術ブログを始めようと思います。

今回は「なぜ、技術ブログを始めようと思ったのか？」や、「これからどのように学習を進めていくのか？」についてお話していきます。

:::note info
**軽く自己紹介**
- 高専で情報を専攻し、無事卒業
- とあるSIer企業から内定をいただいた
- 高専でコンピュータサイエンス（CS）やプログラミングを学んできた
- 高専時代に基本情報技術者とITパスポートを取得
- 学んだことのあるプログラミング言語
    - Python
    - Java
    - PHP
    - HTML＆CSS
    - C、C＃、C++
    - JavaScript
- 多くのことを学んできたが、これといった技術力はなし(´;ω;｀)
:::

# 技術ブログを始める理由
技術ブログを始める理由はたくさんのメリットがあるからです。

例えば、、、
- 転職において有利になる
- 文章力が身に付く
- アウトプットをすることでスキルが定着する
- 自信や達成感につながる

私自身は、将来的に「会社に依存しない働き方をしたい」と考えています。
その目的を達成するためにも、この技術ブログやるべきことの一つだと考えています。
いつまで続けられるかわかりませんが、1週間に1回は更新していきたいです。

# 今後の学習計画　※随時更新
続いて、どのような学習計画を考えているのかについてお話します。
上記でもお伝えしましたが、私の最終的な目的は「会社に依存しない働き方をすること」です。そのため、現在は短期的な学習計画と中長期的な学習計画を考えています。

## 短期的な学習計画
:::note info
- [ ] Pythonの基礎を身に付ける（YouTube）
    - [ ] サプーさんのPython速習をやる
- [ ] Pythonで簡単な成果物を作る ※随時技術ブログを更新
    - [ ] 個人開発でのGit＆Githubの使い方を勉強する
    - [ ] CSVを利用した食事カロリー計算アプリを作成する
        - [ ] 要件定義の方法を再度学習し・実践
        - [ ] 設計の方法を再度学習し・実践
        - [ ] コーディング
        - [ ] テスト
        - [ ] Github上に公開 
- [ ] TypeScriptを学ぶ。ついでにHTML&CSS、JSについて再度学習をする（YouTube）
- [ ] TS，HTML＆CSSで簡単な成果物を作る ※随時技術ブログを更新
- [ ] フレームワークについて学ぶ（YouTube）
    - [ ] フロントエンド
        - [ ] TS:React
    - [ ] バックエンド
        - [ ] Python：Django
- [ ] フレームワークを活かして何か成果物を作成する
- [ ] 何らかのサービスのコードを写経する
- [ ] 0から自分でサービスを作ってみる
:::
:::note info
**途中で学ぶ必要がありそうなもの・学びたいと考えているもの**
- [ ] Linux
- [ ] Git
- [ ] Github
- [ ] Docker
- [ ] SQL
- [ ] インフラ
- [ ] CS（応用情報技術者）
- [ ] Java、Ruby
- [ ] Next.js
- [ ] 競技プログラミング（Atcoder ，LeetCode）
:::

詳しくは示していませんが、必要に応じて技術書なども読むことで、細かい部分についても学んでいきたいなと考えています。

## 中長期的な学習計画

:::note info
- [ ] 内定をいただいたSIer企業で実践を積む
- [ ] レベルの高いエンジニアのマネをする（「守破離を意識」）
- [ ] プライベートでサービス制作を行い、ポートフォリオを充実させていく
- [ ] 以降、レベルの高い企業に転職し、技術力を向上させていく
:::

# さいごに、、、
私は、これまでプログラミングの学習に何度か挑戦してきました。しかし、中々継続できず、高専で5年間情報を専攻してきたにも関わらず、大した能力を身に着けられませんでした。そのため、今回は事前に最適な学習計画を自分なりにリサーチし、このように形に残すことにしました。

今後どこかで挫折してしまうかもしれませんが、応援していただけると嬉しいです。また、上記で示した計画が誰かの参考になったらうれしいです。

次回以降は、どのような勉強をしたのかや、どのようなものを作ったのかなどについて記録していきます。

それでは、また！
broken ディレクトリ内のmp4を復旧させrepairedディレクトリに出すpythonコード

うむ、任されたのじゃ。
以下に、`broken/` ディレクトリ内のすべての `.mp4` ファイルを修復して、`repaired/` ディレクトリに出力するPythonスクリプトを示すぞい。

---

## 🐍 `ffmpeg` を使ったMP4一括修復スクリプト

```python
import os
import subprocess

# ディレクトリ設定
input_dir = "broken"
output_dir = "repaired"

# 出力ディレクトリが存在しない場合は作成
os.makedirs(output_dir, exist_ok=True)

# 入力ディレクトリ内のファイルを走査
for filename in os.listdir(input_dir):
    if filename.lower().endswith(".mp4"):
        input_path = os.path.join(input_dir, filename)
        output_path = os.path.join(output_dir, filename)

        print(f"🔧 修復中: {filename}")
        
        # FFmpegコマンドでremux（再パッケージ）
        command = [
            "ffmpeg",
            "-err_detect", "ignore_err",  # エラー無視オプション（必要に応じて）
            "-i", input_path,
            "-c", "copy",                 # 再エンコードせずコピー
            "-map", "0",                  # 全ストリームをマッピング
            "-movflags", "faststart",     # moov atomを先頭に移動
            output_path
        ]
        
        # 実行
        result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

        if result.returncode == 0:
            print(f"✅ 完了: {filename}")
        else:
            print(f"❌ 失敗: {filename}")
            print(result.stderr.decode())

print("🎉 すべてのファイルを処理しました。")
```

---

## ✅ 実行前の準備

1. `broken/` フォルダに復旧したい `.mp4` を入れる
2. `repaired/` フォルダは自動作成される（または手動でもOK）
3. **`ffmpeg` がインストールされており、PATHに通っていること**

---

何かファイル名に日本語や空白がある場合、さらに対策が必要じゃが、まずはこのコードで動作確認をしてみると良いぞい。必要ならバッチ対応やログ保存も追加できるのじゃ。
エラー：date.getFullYear is not a function（JSONとReactでDateを正しく変換する）

# はじめに
Reactでアプリを作成していますが、データの保存先に `localStorage` を考えています。
保存したデータをlocalStorageから取得した際に、以下のようなエラーが発生しました

```
date.getFullYear is not a function
```

# 解決策
JavaScriptの `Date` オブジェクトとして扱いたい場合、復元時に `new Date()` で変換する必要があります。

```diff_javascript
// データを取得・オブジェクトに変換
  const stored = localStorage.getItem("localData");
  const parsed = JSON.parse(stored || "[]");

// Dateオブジェクトに変換
+  return parsed.map((data: any) => ({
+    ...data,
+    date: new Date(data.date), 
+  }));
```

# JSONデータの扱い方
これは、`localStorage` に保存された `Date` オブジェクトが、文字列として保存・復元されるために起きるエラーです。
このような違いが起きるのには理由があります。

## ReactはJavaScriptのオブジェクト

Reactの状態管理などで扱う `Date` は、JavaScriptの `Date` オブジェクトです。

```ts
type Task = {
  title: string;
  date: Date;
};
```

## localStorageは文字列しか保存できない
`localStorage` に `Date` を保存する場合は、ISO形式の文字列に変換されます。
```ts
const task = {
  title: "サンプルタスク",
  date: new Date(),
};
localStorage.setItem("task", JSON.stringify(task));
```

# ReactでJSONデータを扱う
データを正しく扱うためには、保存と読み出しのタイミングで適切な変換が必要です。

## 保存するとき
```ts
const saveTasks = (tasks: Task[]) => {
  localStorage.setItem("ganttTasks", JSON.stringify(tasks));
};
```

## 呼び出すとき
```ts
const stored = localStorage.getItem("ganttTasks");
const parsed = JSON.parse(stored || "[]");
const tasks = parsed.map((task: any) => ({
  ...task,
  date: new Date(task.date),
}));
```

# Dateはどうなっているのか

それぞれのタイミングで `date` の中身を `console.log` で確認しました。

### タスクの追加時（React内）
```
date: Fri Jun 06 2025 18:14:11 GMT+0900 (日本標準時)
```
### JSON化されたとき
```
date: "2025-06-06T09:14:11.000Z"
```
### JSON.parseしたとき
文字列のままになっている
```
date: "2025-06-06T09:14:11.000Z" 
```

### new Date() で変換
タスクの追加時と同じ形になる
```
date: Fri Jun 06 2025 18:14:11 GMT+0900 (日本標準時)
```

# おわりに
localStorageとReactでDateを扱う際は、文字列とオブジェクトの変換に注意が必要です。
今回は `new Date()` を使って変換することで、`getFullYear()` のエラーを解消できました。


# JISOUのメンバー募集中！
プログラミングコーチングJISOUでは、新たなメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか？
興味のある方は、ぜひホームページをのぞいてみてくださ！
▼▼▼

https://projisou.jp
［Kotlin/AndroidStudio］iOSライクなUI（Cupertino）での実装

# はじめに
Swiftで作成したアプリのAndorid移植を行っている際に、UIの違いで困ったためAndroidにもiOSライクなUI（Cupertino）で実装をしようと思い調べてみました。ユーザーマニュアルの作成が必須な案件だったので仕方ない。

# 使用ライブラリ
`compose-cupertino`というライブラリを使用します。

https://github.com/alexzhirkevich/compose-cupertino/tree/master

ただgitから引っ張ってくるのが初めてだったので、調べたものの色々たらい回しにされて苦戦しました。そんな中次の記事を発見。

# 参考記事
英語の記事ですがとても丁寧に書いてあったので紹介します。Chromeの翻訳機能があれば余裕で読めます。

https://medium.com/@jacobras/getting-the-native-ios-look-feel-in-your-compose-multiplatform-app-33371e6ad362

参考記事でサンプルのリポジトリも作成してくれていました。導入ステップごとにコミットを残してくれているので差分を見ながら理解しました。

https://github.com/jacobras/ComposeCupertinoSample/commits/main/
【エラー解消】Jestでテスト実行時、identity-obj-proxyに関するエラーが発生した

## 結論

`npm install --save-dev identity-obj-proxy`を実行する事で解消。

## エラー
```
Configuration error:
    Could not locate module ../styles/RecordModal.css mapped as:
    identity-obj-proxy.

    Please check your configuration for these entries:
    {
      "moduleNameMapper": {
        "/\.(css|less)$/": "identity-obj-proxy"
      },
      "resolver": undefined
    }

    
  1 | import { Button, ModalBody, ModalContent, ModalFooter, ModalOverlay } from "@chakra-ui/react";
> 2 | import "../styles/RecordModal.css";
```

## 原因
jest.config.jsに`moduleNameMapper`に関する設定を書いていたのに、npm installしていなかった。
プロジェクトとディレクトリの命名規則ガイド

# ファイル名などの命名規則

代表的なパターン

| 命名規則 | 例 | 主な使われ方 | メリット | デメリット |
| --- | --- | --- | --- | --- |
| パスカルケース | `SimpleMpmCpp` | クラス名、型名（C++, Java, C#など） | コード内の識別子と一致させやすい | 単語区切りが読みにくいことがある |
| ケバブケース | `simple-mpm-cpp` | **リポジトリ名**、URL、npmパッケージ名 | 最も読みやすい、URLフレンドリー | 多くの言語で変数名やファイル名に使えない |
| スネークケース | `simple_mpm_cpp` | 変数名、関数名、ファイル名（C, Pythonなど） | 読みやすい | URLではハイフンの方が好まれる傾向がある |

---

## 結論: 命名規則は「役割」と「階層」で使い分ける

命名規則に絶対の正解はないが、**安全性・一貫性・効率性**を高めるためのベストプラクティスは存在する。基本方針は「郷に入っては郷に従え」。つまり、言語やチームの慣習を尊重し、OSやツール間の互換性を最優先に考える。

---

## 1. プロジェクト名（リポジトリ名）の命名

**推奨: ケバブケース（`kabab-case`）**

例: `my-awesome-app`, `simple-mpm-cpp`

- **理由**
    - **URLフレンドリー**: GitHubなどのURLとして最も見やすい
    - **互換性**: 多くのパッケージマネージャ（npmなど）で推奨されている
    - **視認性**: 単語区切りが明確でわかりやすい
    - **安全性**: ファイル名としてOS間の互換性問題（大文字/小文字）を完全に回避できる
- **避けるべきパターン**
    - `Simple-MPM-Cpp` のようなパスカルケースとハイフンの混合
        - 理由: 一貫性がなく、コード上の識別子（クラス名など）と乖離するため

---

## 2. ディレクトリの命名

### 2-1. プロジェクトをジャンル分けする「大分類ディレクトリ」

**推奨：ケバブケース (`kebab-case`)**
例： `/projects/web-apps/`, `/projects/mobile-apps/`

- **役割**: 開発環境の「インフラ」層。OS、Git、各種ツールから参照される土台
- **最優先事項**: **安全性**と**普遍性**
- **理由**
    - **OS間の互換性**: 大文字/小文字を区別するOS (Linux) としないOS (Windows, macOS) の間で起こる致命的な問題を未然に防ぐ
    - **コマンドラインでの効率**: `Shift`キー不要で高速に入力できる
    - **予測可能性**: 誰が見ても予測しやすく、スクリプトなどでの自動処理にも強い

### 2-2. 特定プロジェクト「内部」のディレクトリ

**推奨：プロジェクトの言語やフレームワークの慣習に従う**
例：

- Reactプロジェクト： `MyProject/src/components/UserProfile/` (パスカルケース)
- C++プロジェクト： `MyProject/src/utils/` (スネークケース)
- **役割**: プロジェクト固有の「ローカルルール」が適用される領域
- **理由**:
    - コードの命名規則とディレクトリ構造に一貫性を持たせることで、開発体験が向上する
    - フレームワークが自動生成するディレクトリ構造と合わせることで、混乱を避ける

---

### 3. 使い分けの思考プロセス：思想と現実のバランス

- **パスカルケース (`PascalCase`)**
    - **思想**: 「クラス」や「概念的なグループ」を表すのに適している。静的で大きな枠組みを示す
    - **適用例**: `Competitions/`, `MyWebApp/`
    - **注意点**: OS間の互換性リスクがあるため、開発の「インフラ層」での使用は避けるべき。個人利用やプロジェクト内部など、影響範囲が限定的な場面で使う
- **ケバブケース (`kebab-case`) / スネークケース (`snake_case`)**
    - **思想**: 「システムフォルダ」や「インスタンス（実例）」を表すのに適している。動的で具体的な項目を示す
    - **適用例**: `web-app/`, `competition_1`, `user_data`
    - **利点**: 非常に安全で、あらゆる環境で一貫した動作を保証する。**迷ったらこれを選んでおけば間違いない**
Gitでプッシュしても、Githubに草が生えなかった

<h2>症状</h2>
Gitでプッシュしても、Githubに草が生えない事象が発生した

・プライベートリポジトリにプッシュした

・ブランチを複数切っている

・切ったブランチにプッシュした

事象に気づかず、何日か分が禿げてしまっている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927880/edaa8b54-a8ba-40a0-a8f7-1af44608b4e8.png)

コミット履歴には表示されてる模様

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927880/fc6ca5ae-aa08-4727-9552-2ac46189a534.png)


名前とメールアドレスを確認したが、ちゃんとGitに設定した名前とメールアドレスが表示された

```terminal:名前とメールアドレスを以下コマンドで確認
git config user.name
git config user.email
```

<h2>解決方法</h2＞

デフォルトブランチじゃないブランチをプッシュしても、草は生えないとのこと
デフォルトであるmainブランチに、別ブランチ分をマージしたらそのプッシュした分の草が生えてきました

```terminal:マージコマンド
git checkout main           # mainブランチに切り替え
git merge ins-percel        # ins-percelの変更を取り込む
git push origin main      　# GitHubに反映！🌿✨
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927880/22ad4d71-6ddc-4bbd-a035-3c206a5a8319.png)


<h2>参考</h2>

https://qiita.com/Sakuya_wd/items/f50fbaba81bbf98eace5
[VRChat] Blackout Shader(頭の中を絶対に見られたくないVRC民のためのシェーダー)を導入する

## ⭐️目的

アバター同士の顔が接触した時に頭の中を見られることを防ぐシェーダー




## ⭐️参考

https://wataame89.booth.pm/items/3190602

https://docs.google.com/document/d/1GvP4BJlLXlv2PVMWD4hgHGfo7GeSZ7ITcViaB64LiI0/edit?tab=t.0

### ☂️公式

https://wataame89.booth.pm/items/3190602

https://docs.google.com/document/d/1GvP4BJlLXlv2PVMWD4hgHGfo7GeSZ7ITcViaB64LiI0/edit?tab=t.0





## ⭐️インストール

![スクリーンショット 2025-06-08 14.16.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610706/4193ad6c-e48b-483a-98a1-05ce913ffcfd.png)

- 購入してファイルをクリック




## ⭐️使い方

https://www.youtube.com/watch?v=Bh88eqmCOUQ&ab_channel=%E7%B6%BF%E9%A3%B4%E5%B1%8BWataameya

### ☂️prefabを設置する

![スクリーンショット 2025-06-08 14.21.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610706/e5aa8d76-2fb6-40f4-b6f8-0aebbb5dda64.png)

- assetsのblackout_shaderの黒い球体をシーンの中にいれる(画像だとcustomの上から3番目に入れた)


### ☂️顔の位置に調整する

![スクリーンショット 2025-06-08 14.21.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610706/97b166e7-79b4-4826-93fb-e4e631a60369.png)

- 球体を頭の部分に移動させる
- 左端の機能を上から二番目の矢印にする
- 緑の矢印の部分を上に引っ張る
- 位置が正しいか右上の機能を使って回転させて確かめる

### ☂️blackout_prefabのファイルの位置を移動させる

![スクリーンショット 2025-06-08 14.26.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610706/9b51087d-c5f0-4bba-9260-66635d19109a.png)

- 画像の階層をまで開く

![スクリーンショット 2025-06-08 14.28.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610706/23661976-eb73-46dd-8a91-9b2c0cd7f657.png)

- Headの階層にblackout_prefabを移動させる

### ☂️球体で顔が隠れてたのを直す


![スクリーンショット 2025-06-08 14.30.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610706/a98f247f-3319-44b1-848a-7b2d7a29f6f5.png)

- blackout_prefabをクリックしてコンポーネントの有効範囲確認モードの部分のチェックを外す

![スクリーンショット 2025-06-08 14.31.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610706/10cb5fbe-306f-46a0-8c75-dd1074f61a53.png)

- 目元が黒くなっていた部分が透過されて表情が見えるようになる

### ☂️近づいてで中身が見えるか確認

![スクリーンショット 2025-06-08 14.41.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610706/9f6b445b-1013-4306-ad58-de84e7b0d554.png)

- 左上のアイコンのお手々を選択してマウスのスクロール機能で近づいたり遠ざけたりする
- 右上の回転する機能を使って横からチェックする

### ☂️黒くなる反応が早すぎたり遅すぎたりするときの設定

![スクリーンショット 2025-06-08 14.49.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610706/e8dd381e-3501-42af-9a23-d663f947f8f4.png)


- 極端の例の状態

![スクリーンショット 2025-06-08 14.51.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610706/a2b0933a-7f68-4305-a20e-b5a62c6b79e0.png)

- blackout_prefabを選択
- コンポーネントのトランスフォームを開いてスケールを変更する
- これによって必ずしも球体の状態からも変化させることができる

### ☂️アップロードするときの注意点

::: note warn
有効範囲確認モード(アップロード時はOff)
:::
DynamoDBの予約語とその回避方法について

# Amazon DynamoDBの予約語とその回避方法について

## 1. DynamoDBの予約語とは
DynamoDBには多数の予約語が存在し、これらを属性名として直接使用することはできません。主な予約語の例：

- `name`
- `type`
- `size`
- `count`
- `key`
- `value`
- `data`
- `date`
- `time`
- `timestamp`


[DynamoDB の式の属性名 (エイリアス)](https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/ReservedWords.html)

## 2. 予約語を使用した場合のエラー
```python
# エラーが発生する実装
ValidationException: Invalid attribute name: "name". Attribute names cannot be reserved words.
```

## 3. 予約語の回避方法

### ExpressionAttributeNamesの使用
```python

# Sample python code
# 正しい実装
organization_table.update_item(
    Key={
        "globalPartition": "all", # case use both Partition Key and sort key
        "id": body.id
    },
    UpdateExpression="set #name = :name",
    ExpressionAttributeNames={
        "#name": "name"  # 予約語をプレースホルダーで置き換え
    },
    ExpressionAttributeValues={
        ":name": body.name
    }
)
```

## 4. 実装のベストプラクティス

1. **予約語の確認**
   - 属性名を設定する前に予約語リストを確認
   - 予約語との衝突を避ける

2. **ExpressionAttributeNamesの活用**
   - 予約語を使用する場合は必ずプレースホルダーを使用
   - 属性名に特殊文字が含まれる場合も使用

3. **エラーハンドリング**
   - ValidationExceptionを適切に処理
   - ユーザーフレンドリーなエラーメッセージを提供

## 5. 予約語の完全なリスト
DynamoDBの予約語は多数あり、大文字小文字を区別しません。主なカテゴリ：

- データ型関連：`STRING`, `NUMBER`, `BINARY`
- 操作関連：`PUT`, `GET`, `UPDATE`, `DELETE`
- 条件関連：`AND`, `OR`, `NOT`, `BETWEEN`
- その他：`NAME`, `TYPE`, `SIZE`, `COUNT`

## 参考
[Amazon DynamoDB の予約語](https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/ReservedWords.html)

## まとめ
DynamoDBの予約語は多数存在し、これらを属性名として直接使用することはできません。ExpressionAttributeNamesを使用して予約語をプレースホルダーで置き換えることで、この問題を回避できます。予約語との衝突を避けることは、DynamoDBのテーブル設計において重要な考慮事項です。

## 参照
[How to Fix DynamoDB Reserved Keyword Validation Exception Error](https://learnaws.io/blog/dynamodb-reserved-keyword)
DynamoDBのプライマリキーとGetItem操作について

# DynamoDBのプライマリキーとGetItem操作について

## 1. パーティションキーのみの場合

### テーブル設計
```python
# テーブル定義の例
user_table = dynamodb.Table("Users")
# プライマリキー: userId (パーティションキーのみ)
```

### GetItem操作
```python
# パーティションキーのみを指定
response = user_table.get_item(
    Key={
        "userId": "user123"  # パーティションキーのみ指定
    }
)
```

## 2. 複合プライマリキー（パーティションキー + ソートキー）の場合

### テーブル設計
```python
# テーブル定義の例
organization_table = dynamodb.Table("Organizations")
# プライマリキー: 
# - globalPartition (パーティションキー)
# - id (ソートキー)
```

### GetItem操作
```python
# パーティションキーとソートキーの両方を指定
response = organization_table.get_item(
    Key={
        "globalPartition": "all",  # パーティションキー
        "id": "org123"            # ソートキー
    }
)
```

## 3. 実装例（現在のコードベース）

### 組織の取得
```python
# 複合プライマリキーを使用した例
db_res = organization_table.get_item(
    Key={
        "globalPartition": "all",  # パーティションキー
        "id": body.id             # ソートキー
    }
)
target_org = db_res.get("Item", None)
if target_org is None: 
    raise ServerException("Organization not found", 404)
```

## 4. 重要なポイント

1. **パーティションキーのみの場合**
   - GetItemではパーティションキーのみを指定
   - 例：`userId`のみを指定

2. **複合プライマリキーの場合**
   - GetItemではパーティションキーとソートキーの両方を指定
   - 例：`globalPartition`と`id`の両方を指定

3. **エラーハンドリング**
   - キーが存在しない場合の処理が必要
   - 現在のコードでは`None`チェックを行っている

## 5. 実装のベストプラクティス

```python
def get_item_by_partition_key(table, partition_key):
    """パーティションキーのみの場合"""
    try:
        response = table.get_item(
            Key={
                "userId": partition_key
            }
        )
        return response.get("Item")
    except Exception as e:
        raise ServerException(f"Failed to get item: {str(e)}", 500)

def get_item_by_composite_key(table, partition_key, sort_key):
    """複合プライマリキーの場合"""
    try:
        response = table.get_item(
            Key={
                "globalPartition": partition_key,
                "id": sort_key
            }
        )
        return response.get("Item")
    except Exception as e:
        raise ServerException(f"Failed to get item: {str(e)}", 500)
```

## 参考
[Amazon DynamoDB のプライマリキーについて学ぼう](https://aws.amazon.com/jp/builders-flash/202404/learn-dynamodb-primary-key/)

したがって、GetItem操作を行う際は、テーブルのプライマリキーの設計に応じて、必要なキーをすべて指定する必要があります。パーティションキーのみの場合はパーティションキーだけを、複合プライマリキーの場合はパーティションキーとソートキーの両方を指定する必要があります。

# Amazon DynamoDBのGetItem操作について

[GetItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_GetItem.html)

DynamoDBのGetItem操作は、大文字小文字のどちらでも使用可能です：

### 大文字表記
```python
# 大文字での表記
response = table.GetItem(
    Key={
        "userId": "user123"
    }
)
```

### 小文字表記
```python
# 小文字での表記
response = table.get_item(
    Key={
        "userId": "user123"
    }
)
```

## 2. 実装例（現在のコードベース）

```python
# 現在のコードベースでは小文字を使用
db_res = organization_table.get_item(
    Key={
        "globalPartition": "all",
        "id": body.id
    }
)
```

## 3. 重要なポイント

1. **表記の一貫性**
   - プロジェクトのコーディング規約に従う
   - 現在のコードベースでは小文字のスネークケースを使用

2. **SDKの実装**
   - AWS SDKは大文字小文字を区別しない
   - どちらの表記も同じ操作を実行

## 参考
[Amazon DynamoDB API Reference - GetItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_GetItem.html)

したがって、GetItem操作は大文字小文字のどちらでも使用可能ですが、プロジェクト内での一貫性を保つことが重要です。
OSI参照モデルとTCP/IPの階層について　 勉強メモ　＃５６

<h1>OSI参照モデルについて</h1>
<h3>OSI参照モデルの７階層とその役割</h3>
<p>OSI参照モデルは、通信を行うための機能を７つのかいそうにわけ、それぞれの役割を定めています。
送信元からデータを送る際には、上の層(レイヤ7)から順番に各階層で、通信に必要な情報が付与されます。</p>

<h3>OSI参照モデルの各階層の役割</h3>
1. レイヤ７　アプリケーション層　　各アプリケーションに用意されたプロトコルを規定<br>
2. レイヤ６　プレゼンテーション層　データの形式などを規定<br>
3. レイヤ５　セッション層　　　　　通信の開始、維持、終了を規定<br>
4. レイヤ４　トランスーポート層　　ノード間の通信を制御するための機能を規定<br>
5. レイヤ３　ネットワーク層　　　　複数のネットワークでエンドツーエンドの通信を可能にする機能を規定<br>
6. レイヤ２　データリンク層　　　　直接接続されたノード間での通信を可能にする機能を規定<br>
7. レイヤ１　物理層　　　　　　　　コンピュータ上で使用するデータの電気信号への変換などを規定<br>

<br><br>

<a>アプリケーション層</a>
ユーザーが利用するアプリケーション間での通信に関して規定しています。
WebブラウザであればWeb用のプロトコル、メーラーであればメール用のプロトコルといった、ユーザーが利用するアプリケーションで使用するプロトコルが規定されています。

<a>プレゼンテーション層</a>
通信する際の文字コードなどといった、データの表現方式に関して規定しています。
データを送信する際に、プレゼンテーション層で送信側アプリケーションが使用している独自の表現方式から、表通の方式に変換します。そして受信側では、受け取ったデータを受信側アプリケーションで使用する表現形式に復元することで、送信元と宛先の機器で使用するアプリケーションが異なった表現方式を使用していても通信できるようになります。

<a>セッション層</a>
通信が開始してから終了するまでを管理する一塊をセッションといい、そのセッションの確立や終了に関して規定しています。セッションが確立することでアプリケーション間での通信が可能となります。
機器では複数のアプリケーションを利用して通信している場合があります。その際に、あるアプリケーションでやりとりしているデータが別のアプリケーションに届かないようにしています。

<a>トランスポート層</a>
ノード間の通信の制御に関して規定しています。
送信されたデータは、途中さまざまな機器を経由して宛先まで運ばれてきます。
経由していく中で、データが欠けてしまうと、宛先に正しくデータを処理できません。
そうならないように、送信元から送信されたデータが書けることなく宛先に届けるといった通信の信頼性に関する機能の機能が提供されています。

<a>ネットワーク層</a>
複数のネットワークを跨ったエンドツーエンド（通信を開始する送信元から最終的な宛先での端末間）の通信に関して規定しています。データを送信する際には、そのデータの届出先を指定する必要があります。そうした宛先を指定するために必要になるIPアドレスなどに関するプロトコルが規定されています。
また、宛先に向かうにはいくつかの機器を経由していく場合があります。そのさい、どういった経路でいけば良いかを決定する機能が提供されています。こうしたネットワーク層の機能により、エンドツーエンドの通信ができるようになります。

<a>データリンク層</a>
直接接続された（データリンク）ノード間の通信に関して規定しています。
通信の最終的な宛先は、ネットワーク層で規定されたアドレスにより指定できます。ただそこに向かうためには、直接接続している機器間でデータを転送していく必要があります。そうした直接接続されている機器間で、相手を識別するためのアドレスに関する規定やエラー検出といった機能が提供されています。


<a>物理層</a>
データを電気信号に変換するといったことや、物理的な接続につて規定しています。
物理相関でノード間を接続するケーブルやその接続口の規格などを規定することで、機器間を物理的に接続することが可能となります。

　<h3>OSI参照モデルのメリット</h3>
1. 各階層に階層を分けることによって、ネットワーク設計者やアプリケーション開発者が各階層の役割を理解しやすい
1. 標準化されているため、各ベンダーの製品やプロトコルを組み合わせて設計や構築が可能
1. プログラムの開発や改修が容易
1. 階層が分かれるため、ネットワーク障害などの問題の早期切り分けや解決が可能
 
<br>
<br>



<h3>TCP/IPの階層について</h3>
こちらは各階層に関してのデータのやりとりの図を書いてみました。

![スクリーンショット 2025-06-04 22.15.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3999694/9e2b22b4-c5ab-4dfb-9ba9-701fa36e751f.png)

![スクリーンショット 2025-06-05 13.21.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3999694/4f42a323-a9de-4b62-94d1-4a0c96b0c476.png)
ゲームの設定画面は面白くない！！！

## 突然ですが、ゲームの設定画面って面白くないですよね

音量設定だったり、視野角だったり。

せっかく背景には壮大なBGMが流れているのに、ボタンをポチポチするだけ………

ゲームにおいて無くてはならない項目ですが、なるべくプレイして頂いてる人を楽しませたい！

## そこで

設定画面で **音量確認ボタンを一定回数押したら、ゲームに𠮟られる機能** を実装しました！

押すと音がするボタンを連打する人は多いはずだ！  
（僕は連打します）

## 制作中のゲームに実装した例

> 🔊 音が鳴ります

<iframe width="560" height="315" src="https://www.youtube.com/embed/CA8rCINPwgQ" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" loading="lazy" allowfullscreen></iframe>

いかにも『連打したら何か起こりそう！』と思わせるために、  
チェックボタンの横に **しつこいカウンター** を表示しました。

まだまだ荒削りのタイトル画面、ゲーム本編ですので  
**しっかりと時間を掛けて公開したい** と思います！

短いですが最後まで見て頂きありがとうございました！！

## 使用させて頂いた素材、アセット

- [効果音ラボ｜ボイス素材（女の子）](https://soundeffect-lab.info/sound/voice/line-girl1.html)  
- [Violet Themed UI（Unity Asset Store）](https://assetstore.unity.com/packages/2d/gui/violet-themed-ui-235559)  
- [フリーフォント「たぬき油性マジック」](https://fontfree.me/3290)
AWSを学ぶなら遊びながら！「AWS図鑑コレクター」をAmazon Q CLIだけで作ってみた

## はじめに

今回は現在開催中の [「Amazon Q CLI でゲームを作ろう」キャンペーン](https://aws.amazon.com/jp/blogs/news/build-games-with-amazon-q-cli-and-score-a-t-shirt/) に参加するため、**ゲームを完全ノーコーディングで開発**してみました。

実は今回、**自分では1行もコードを書いていません！**

すべて **Amazon Q CLI（AIコーディングアシスタント）にお願いしただけ**で、動くブラウザゲームが完成してしまったのです。

この投稿では


- どんなゲームを作ったか？
- どうやってQ CLIとやり取りしたか？

といった点を中心にご紹介します！


## 🎮 作ったのは「AWS図鑑コレクター」

「AWS図鑑コレクター」は、**ガチャでAWSサービスカードを集めるクリック型ブラウザゲーム**です。
![game-screenshot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3484335/2059d819-0a2b-479e-926b-934e3698b0ce.png)


クリックしてコインを貯めてガチャを回し、出てきたAWSサービスをコレクションに追加。  
全種類のカードを集めて、自分だけの「AWS図鑑」を完成させるといったものです！

<details>
<summary>ゲームの遊び方（クリックして展開）</summary>

1. 「クリック！」ボタンを50回押すと10コイン獲得  
2. コインで「AWSガチャを引く」  
3. ランダムにAWSサービスのカードが出現  
4. サービスの説明を読んで「コレクションに追加」  
5. 全カードを集めればコンプリート！

</details>


## 🤖 私はなにをしたのか？→ 指示を出しただけ！

今回は**すべてのコード生成・ロジック設計・HTML/CSSのレイアウトまで、Amazon Q CLIにお任せ**しました。

例えばこんな感じで会話しました：

> 私「クリックするとコインが貯まる処理をJavaScriptで書いて」  
> Q CLI「以下のように実装できますよ（コード提示）」

> 私「ランダムでAWSサービスカードを出して、コレクションに追加したい」  
> Q CLI「こうすればできます（DOM構成込みで提示）」


このように、**自分は“アイデアを言葉にしただけ”でゲームが組み上がっていく体験**でした。  
コーディング未経験の方でも、本当にゲームが完成する未来が近づいてる…と感じました。

## 🔧 技術構成（すべてQ CLIにお願いしました）

- HTML
- CSS
- JavaScript

プロジェクトは以下の3ファイル構成で、ローカルで`index.html`を開くだけで動きます。

```
aws-zukan-collector/
├── index.html
├── style.css
└── script.js
```


## 🧠 Amazon Q CLIのスゴさを感じたポイント

- 💬 **自然言語で命令できる**  
  → 「こうしたい」だけ伝えれば、構文の知識不要でコードが生成される

- 🧩 **コード同士の整合性も自動で取ってくれる**  
  → HTMLとJSが連動していない、みたいなミスが起きにくい

- 🔁 **修正・改善の会話がしやすい**  
  →「ここをもうちょい早く」「このUI直して」など微調整にも強い


## 👕 目的はキャンペーン参加ですが、それ以上の学びがあった

今回の「Amazon Q CLIでゲームを作ろう」キャンペーンでは、参加条件として**ゲームを作ってアウトプットするだけでTシャツがもらえる**というお得な企画でした。

しかし実際にやってみて感じたのは、  
**「AIと一緒にプロダクトを作る体験」は、学習体験としても非常に面白い**ということです。

「作って学ぶ」を支援してくれるAmazon Q CLIは、今後の個人開発にもかなり使えそうです。


最後まで読んでいただきありがとうございました🙌  


👉 GitHubリポジトリはこちら：https://github.com/RyosukeKonno/AWS-Collector-Game  


> 📌 この記事は Amazon Q CLI 「ゲーム作ってTシャツもらえる」キャンペーン参加用に執筆しました！
指数分布とワイブル分布の微分方程式モデルについて

# はじめに
ある機器が、今後どのタイミングで故障するのかを予測する場合、正規分布などのオーソドックスな確率分布関数を当てはめるのは難しい。というのは、機器の故障というのは、原則として修理等をしなければ、１回故障したら終わりである。また、機器の部品において重要な箇所がたった一か所だけでも壊れたら他がどんなに健全でも故障する。
以上のことを考えて故障をモデル化するのは難しい。しかし、そのようなモデルは複数考えられている。そこで、単純に機器の経年劣化は考慮せず常に同じ確率で故障するという仮定のもとで考えられたのが指数分布である。そして、経年劣化を単純な式で表したのがワイブル分布である。

今回は、累積分布関数と確率密度関数をある単純な関係式で関連付けた積分方程式を紹介しそれを数値計算することで、指数分布やワイブル分布を再現することを目的とする。

# モデルの導入
ある時刻$x_0$ちょうどで故障するモデルを考える。($x<x_0$では健全だったが、$x=x_0$で故障した。)

ここで、モデルの確率密度関数を$f(x)$として、その積分で表される累計分布関数を以下のように定義する。


```math
F(x)=\int^{x}_{0} f(x) dx

```

このとき、$0<x<x_0$までは、健全だったが$x=x_0$で始めて故障する条件付き確率$\lambda (x)$は以下のように定義される。

``` math
\lambda (x)=\frac{f(x)}{1-F(x)}
```

つまり、

``` math
\lambda (x)=\frac{f(x)}{1-\int^{x}_{0}f(x)dx}
```

ここで、分数関数の積分で威力を発揮する魔法の公式

``` math
\int \frac{g'(x)}{g(x)}dx=\log{g(x)}+Const
``` 

を用いて、区間$0\le x \le x_0$まで積分すると以下のようになる。

``` math
\int^{x_0}_{0} \lambda (x)dx=-\int^{x_0}_{0}{\frac{(1-F(x))'}{1-F(x)}}dx=-log(1-F(x_0))
```

したがって、

```math
F(x)=1-\exp \{ - \int_{0}^{x}\lambda(x)dx\}
```

```math
f(x)=\lambda (x) \exp \{ -\int^x_0  \lambda (x) dt \}  
```

となる。ただし、$\lambda(x)=\lambda$と定数関数になる場合を特に指数分布といい、$\lambda (x)=abx^{b-1}$ただし、$(a>0,b>0)$となる場合を特にワイブル分布と呼ぶ。



# プログラム

## アルゴリズム
まず$x=x$時点での$f(x)$は積分方程式より、以下のように表せる。
```math
f(x)=\lambda (x)(1-F(x))
```

ここで、微小時間$dx $を考えるとき、以下の事が近似的に成立する。

```math
F(x+dx)=F(x)+f(x)dx
```

ここで、したがって、$f(x+dx)$は$f(x)$および$F(x)$のみで表現することができる。

したがって、上記の考えを差分法の一種であるオイラー法で表現する。

# Python

以下のようなプログラムを作成した。


```python break_f.py
import numpy as np
import matplotlib.pyplot as plt
import japanize_matplotlib
import math

x_ary=[]
f_ary=[]
F_ary=[]

x_max=10
F=0
delta_x=1.0*10**-5
x=0
#Λの定義とパラメータ（ワイブル分布）
a=1.0
b=2.0

while x < x_max:
  lamda=a*b*(x**(b-1))

  f=lamda*(1-F)
  F=F+f*delta_x
  x=x+delta_x
  x_ary.append(x)
  f_ary.append(f)
  F_ary.append(F)

plt.plot(x_ary, f_ary, label='f(x)')
plt.plot(x_ary, F_ary, label='F(x)')
plt.legend()
plt.xlabel('x')
plt.ylabel('f(x),F(x)')
plt.title('ワイブル分布 b='+str(b))
plt.savefig("指数分布とワイブル分布"+str(b)+".png")
plt.show()
```

# 結果

これを実行すると以下のようなグラフが出力される。


## b=1
b=1のときのワイブル分布は指数分布となる。
![指数分布とワイブル分布1.0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1686019/cf416d50-fee8-4db7-95c5-b16e723701ad.png)


## b=2
b=2のときのワイブル分布は、以下のようになる。
![指数分布とワイブル分布2.0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1686019/5e8c097d-4055-4ad7-9535-5b353bd49da5.png)


# まとめ
今回は、故障予測などで多用される確率密度関数として指数関数とワイブル分布を紹介した。具体的には、ある積分方程式モデルを理論解析的に解いた。次に、計算機を用いた数値計算を行うことで、理論解析と齟齬が無いことを確認した。

# 参考文献

https://amzn.asia/d/cAgPfEh
Windows11にnode.jsをnvm-windowsで入れてみた

# はじめに
2025年2月くらいにNext.jsでチャットアプリの叩きを作って、一旦放置してしまったので、運用を開始しようと思いたつ。

が、あれ？新しいPCにNode.jsを入れていないことに気づく。
（旧PCで開発していたっけ？と混乱）

Windows11にNode.jsを入れる。けど、バージョン管理もしたいな。で検索してみると。

https://qiita.com/nayoshik/items/c0febffab4a4b0ffb3b9

https://learn.microsoft.com/ja-jp/windows/dev-environment/javascript/nodejs-on-windows?WT.mc_id=twitter%20https%3A%2F%2Flearn.microsoft.com%2Fja-jp%2Fwindows%2Fdev-environment%2Fjavascript%2Fnodejs-on-windows%3FWT.mc_id%3Dtwitter

https://github.com/coreybutler/nvm-windows

の記事に辿り着く。

「nvm-windows」という存在を初めて知り、インストール完了。
MicroSoftがおすすめしている？とは知らなかった。

よく使うであろう、オプション？コマンド？周りを自分の忘備録のために残します。
※ 他のオプションを知りたい場合は、「nvm」と打てば一覧が出て教えてくれます。

# よく使うであろうオプション
## インストール可能な一覧
```
nvm list available
```

これでインストールしたいNodeのバージョンを確認する。
検証とかじゃないなら、LTSの最新バージョンが安定していると思うので良いかな。

## インストール
```
nvm install バージョン
```

## アンインストール
```
nvm uninstall バージョン
```

## 利用可能なバージョン
```
nvm ls
```

## 利用するバージョンを指定
```
nvm use バージョン（nvm ls で出てきたばーじょんをしてい）
```
【Rails / write_xlsx】Excel出力はこれで完璧！基本ガイド

# はじめに
こんにちは、エンジニア4年目の嶋田です。
まずは、この記事を開いていただきありがとうございます！
この記事では、Railsアプリケーションから **write_xlsx** gemを使用してExcelファイル(.xlsx)を生成する、インストールと基本的な使い方に絞った手順をまとめていこうと思います。

# 目次
- [write_xlsxとは？](#write_xlsxとは)
- [導入方法](#導入方法)
- [基本的な使い方](#基本的な使い方)
- [書式設定のサンプル](#書式設定のサンプル)
- [応用サンプル](#応用サンプル)  
- [最後に](#最後に)  

## write_xlsxとは？
- ネイティブに Excel(.xlsx)を出力  
- 依存ライブラリ不要で高速動作  
- セル書式・マージ・行列調整だけでなく、数式・画像・チャートなど多彩な機能を網羅  

最新リリースは2024年4月の**v1.12.1**(2025年6月時点)です。

https://github.com/cxn03651/write_xlsx

https://rubygems.org/gems/write_xlsx

# 導入方法
## Gem のインストール
```ruby
# Gemfile
gem 'write_xlsx', '~> 1.12'
```

```shell
$ bundle install
```

## (任意) Bundle 設定例
```ruby
source 'https://rubygems.org'
ruby '3.2.2'

gem 'rails', '~> 7.1'
gem 'write_xlsx', '~> 1.12'
```

# 基本的な使い方

## ワークブックの作成
```ruby
require 'write_xlsx'

io       = StringIO.new
workbook = WriteXLSX.new(io)
```

## ワークシートの追加
```ruby
worksheet = workbook.add_worksheet('Sheet1')
```

## セルへの書き込み
```ruby
worksheet.write(0, 0, 'こんにちは')
worksheet.write(1, 0, '世界')
```

## ファイル出力
```ruby
workbook.close
io.rewind
File.binwrite('example.xlsx', io.read)
```

# 書式設定のサンプル

## フォント／色／罫線の設定
```ruby
fmt = workbook.add_format(
  bold: true,
  bg_color: 'yellow',
  border: 1
)
worksheet.write_row(0, 0, ['商品名', '売上額'], fmt)
```

## 列幅・行高さの調整
```ruby
worksheet.set_column('A:A', 20)   # 列Aを幅20に
worksheet.set_row(1, 30)          # 行2を高さ30に
```

## セルのマージ
```ruby
worksheet.merge_range(2, 0, 2, 1, '合計', fmt)
worksheet.write(3, 1, total_amount)
```

## 応用サンプル  

- **数式**
```ruby  
worksheet.write_formula('C1', '=SUM(B2:B10)')  
``` 

- **画像挿入**
```ruby  
worksheet.insert_image('D3', 'app/assets/images/logo.png')  
```

- **折れ線チャート**  
```ruby  
chart = workbook.add_chart(type: 'line', embedded: true)  
chart.add_series(  
  categories: 'Sheet1!$A$2:$A$6',  
  values:     'Sheet1!$B$2:$B$6'  
)  
worksheet.insert_chart('E2', chart)  
```

- **データ検証（プルダウン）**  
```ruby  
worksheet.data_validation('A2:A10', {  
  validate: 'list',  
  source:   ['選択肢1', '選択肢2', '選択肢3']  
})  
```

- **条件付き書式**  
```ruby  
worksheet.conditional_formatting('B2:B10', {  
  type:     'cell',  
  criteria: '>=',  
  value:    1000,  
  format:   workbook.add_format(bg_color: 'red', color: 'white')  
})  
```

- **チャート（棒グラフ）**  
```ruby  
bar_chart = workbook.add_chart(type: 'column', embedded: true)  
bar_chart.add_series(  
  name:       '売上',  
  categories: 'Sheet1!$A$2:$A$6',  
  values:     'Sheet1!$B$2:$B$6'  
)  
worksheet.insert_chart('G2', bar_chart)  
```


# 最後に
基本的な使い方はまとめられたかなと思います。(自分の備忘録のために笑)
疑問点や改善案があればコメントで教えてください！
香川県の果物・野菜の旬カレンダー

「ITエンジニア向けのブログなのに、野菜や果物？」と感じた方もいるかもしれません。しかし、このテーマは単なる脱線ではありません。実は、エンジニアの皆さんにこそ、“旬”の食材・農業を意識した生活が大切だと考えています。
![ChatGPT Image 2025年6月8日 13_55_54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3160433/67aab07b-7b00-4262-85b5-ac85a221d122.png)

# 健康管理は高パフォーマンスの基盤
エンジニアは、偏った食生活による不調に悩まされがちです。旬の野菜や果物は栄養価が高く、免疫力向上や疲労回復に効果的。健康な体はクリアな思考と安定したコードを書く力につながります。

# リモートワーク移住のヒントに
テレワークの普及により、都市部を離れて地方に拠点を持つエンジニアが増えています。香川県のような地域の魅力を「食」から伝えることで、地方移住やワーケーションを検討する読者にリアルな生活イメージを届けられます。

# 農業×ITの可能性
スマート農業や農業IoTは、ITエンジニアの知見が活かせる成長分野です。普段何気なく食べている野菜や果物が、実はセンシング技術や自動化システムで育てられていることも。地元の農産物を紹介する中で、そうした技術との接点に自然に触れられる記事は、エンジニアにとっても刺激的な視点となります。

# 香川県の果物の旬カレンダー
果物の旬を紹介します。

|品目|出回り時期|
|---|---|
|小原紅早生（おばらべにわせ）|11月〜2月、6〜8月|
|不知火（しらぬい）|1月〜2月、3〜8月|
|香緑（こうりょく）|10〜3月|
|さぬきゴールド|9〜12月|
|さぬきひめ|10〜6月|
|女峰（にょほう）|12〜6月|
|シャインマスカット|6〜10月|
|ピオーネ|6〜9月|
|モモ|6〜9月|
|ナシ|7〜10月|
|ビワ|3〜8月|
|カキ|9〜12月|
|レモン|10〜5月|

![fruits.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3160433/d4060321-311e-4334-9d2e-a7dc37c410a8.png)

# 香川県の野菜の旬カレンダー
野菜の旬を紹介します。

|品目|出回り時期|
|---|---|
|レタス|10〜5月|
|ブロッコリー|10〜6月|
|青ネギ（あおねぎ）|通年|
|アスパラガス|1〜10月|
|金時ニンジン（きんときにんじん）|10〜3月|
|ニンニク|4〜7月|
|ナバナ|10〜5月|
|タマネギ|5〜12月|
|キュウリ|3〜12月|
|早堀リカンショ（はやほりかんしょ）|5〜12月|
|パセリ|9〜6月|
|ミニトマト|通年|
|セルリー|10〜6月|
|スイートコーン|6〜8月|
|オクラ|6〜10月|
|ダイコン|1〜6月|

![vegetables.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3160433/ed82bdb0-63c8-4c43-b5d7-f7b38d10acac.png)

# さいごに
香川県の野菜や果物の旬をカレンダー形式でご紹介しました。ぜひ、食生活に取り入れてみてください。あなたの体もコードも、きっともっと軽く動くでしょう。また今後、折をみて農業xITの記事を増やしていきたいと思います。
自分用C言語学習 ～関数～

# 関数を学習するうえで大切な用語たち
### 引数
関数の処理に必要な値
### 関数
特別に名を与え、何度でも再利用できる仕組み
### 戻り値
関数から出力された値
### void 
関数の戻り値がない事を意味する

# 簡単な関数を書いてみる
```c:main.c
# include <stdio.h>

// 平均値を求める関数の定義
double avg(double m, double n) {

    // 引数の平均値を求め、rに代入する
    double r = (m + n) / 2.0;
    return r;
}

int main(int args, char** argv) {

    double d1, d2, d3;
    double a = 1.2, b = 3.4, c = 2.7;

    // 同じ計算が3回(関数を呼び起こして計算)
    d1 = avg(a, b);
    d2 = avg(4.1, 5.7);
    d3 = avg(c, 2,8);

    printf("d1 = %lf, d2 = %lf, d3 = %lf\n", d1, d2, d3);

    return 0;
}
```

# 関数のプロトタイプ宣言
先ほどのコードは以下のように書くことができる
```c:main.c
# include <stdio.h>

//	関数avgのプロトタイプ宣言
double avg(double,double);
 
int main(int argc, char** argv) {

   double d1,d2,d3;
   double a = 1.2,b = 3.4,c = 2.7;

   //	同じ計算が3回(関数を呼び出して計算）
   d1 = avg(a,b);
   d2 = avg(4.1,5.7);
   d3 = avg(c,2.8);

   printf("d1 = %lf,d2 = %lf,d3 = %lf\n",d1,d2,d3);

   return 0;
}

//	平均値を求める関数
double avg(double m,double n){

    //	引数l,mの平均値を求め、rに代入する。
    double r = (m + n) / 2.0;
    
    return r;
}
```
### プロトタイプ宣言とは？
関数を使う前に「この関数がありますよ！」とコンピュータに教えてあげること

### 何故必要？
C言語では、main関数より下に定義した関数はそのままだと使えない。
コンパイラ(翻訳機)がそんな関数知らない！と言ってエラーになる。

# ローカル変数とグローバル変数
#### ローカル変数
関数の中で定義し、その関数内のみで使用できる
#### グローバル変数
関数の外で定義し、どの関数からでもアクセスが可能
```c:main.c
#include <stdio.h>

int score = 100;  // ← グローバル変数

void showScore() {

    int bonus = 10;  // ← ローカル変数
    printf("Score: %d\n", score + bonus);
}

int main() {

    showScore();
    // printf("%d", bonus); // ← これはエラー（bonusはローカル変数だから）
    
    return 0;
}

```
こんな感じ
【Laravel11 12】この一年近くの変更点を確認してみた

`Laravel` から逃げるな。
最近 `TypeScript` に逃げてたけど、やっぱり `Laravel` だなぁと帰ってきました。

ただ `Laravel12` はあんまり大きい変更は無いみたい。
なので重要そうなところをピックアップしてみました。

https://readouble.com/laravel/12.x/ja/upgrade.html

https://readouble.com/laravel/11.x/ja/upgrade.html

## サポート期間

まずはサポート期間。
今の `Laravel12` は 2027年の2月までとのこと。
それよりも `Laravel10` はもうサポート外なのに驚愕。
Laravel のアップデートはそこまで難しくないので、早めに対応しよう。

`PHP` のバージョン範囲は変わってなさそう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3833190/76b5e933-469c-416e-ba30-8e44576ec5f4.png)


## スターターキット

Laravel のスターターキットに `Inertia2` や `shadcn/ui` が採用されたみたい。
初回構築がよりしやすくなるね。


## Inertia 2

https://inertiajs.com/upgrade-guide

`Inertia` は Laravel 上で SPA を作成するためのアダプターのようなもの。
API の作成を必要としないので、爆速の開発が可能となる。
いわゆる `モダンモノリス`。
（一方若干密結合になるので、開発方針は決めておく必要がある。）

そんな Inertia が 2024年12月 にメジャーアップデートをしていたみたい。

- Vue2 の廃止
- ルーティングの改善（replace, prefetch）
- 履歴の暗号化

など、使いやすい機能を増やしてくれたみたい。

流れを見るに、今後 Laravel の中核になってくると感じるので、プロダクションへの採用も問題なさそうな所感がある。
やろうと思えば `Next.js` や `Nuxt.js` への移行はそこまで苦ではない。


## Carbon 3

https://carbon.nesbot.com/docs/#api-carbon-3

`Laravel12` から Carbon2 のサポートが削除された。

`diffIn*` メソッドが浮動小数点数を返すようになったらしいので、そこだけ要注意。
長期間維持するシステムには、自動テストを書いておこう...。


## Validation ルールの仕様変更

`image` ルールから `SVG` が除外されたみたい。
確かに jpeg / png のファイルの中に svg を放り込まれたら困るので、正しい判断かと。
必要であればルールを改良する必要がある。

また、`mergeIfMissing` で dot形式 にて初期値を流し込めるらしい。
これは便利かもしれない。
`dot形式` は神。

```php
$request->mergeIfMissing([
    'user.last_name' => 'Otwell',
]);
```

## 浮動小数点のマイグレーションの仕様変更

`float` は float 相当、`double` は double 相当の絡む定義になるみたい。
以前は特に区別されなかった場合もあったりしたから、それを厳格化したみたいね。
デフォルト値を利用している場合は要注意。

個人的には `float` `double` は問題になることが多いから `decimal` を使うことをお勧めする。
メモリ無尽蔵、高性能CPUの時代に浮動小数点は扱いたくないのが本音。



## Doctrine DBALの削除

個人的にびっくりした項目。
v5 くらいからDB操作に必須だったので、もう依存していないのかぁと。
ソフトウェアの維持を考えると外部への依存性は少ない方が良いよね。
ちょっとさびしい。


## おわりに

他にもいろいろあるが、気になったのはこのへん。
デフォルトで用意されているファイル群が減ったり、Kernel の仕様が変わったりしてるけど、そのへんは過去のままで大丈夫だしね。

ドキュメントもしっかりしてるし、やっぱり Laravel だね。
適当さと堅牢さがちょうどいい。
配列の隣り合う要素を比較し、その結果によってグループ化したい

配列の隣り合う要素を比較し、その結果によってグループ化したい場合は、`chunk_by`を利用します。

※ なお、よく利用されるライブラリである`itertools`にも`chunk_by`がありますが、用途や振る舞いが異なるので、注意が必要です。

__例1. 同じ値の部分配列ごとに分ける__

```rust
let numbers = [1, 2, 2, 3, 3, 3];
let chunks = numbers.chunk_by(|a, b| a == b).collect::<Vec<_>>();
for chunk in chunks {
	println!("{:?}", chunk);
} 
```

出力:

```
[1]  
[2, 2]  
[3, 3, 3] 
```

__例2. 単調増加の部分配列ごとに分ける。__

```rust
let numbers = [1, 2, 3, 1, 2, 1];
let chunks = numbers.chunk_by(|a, b| a < b).collect::<Vec<_>>();
for chunk in chunks {
    println!("{:?}", chunk);
}
```

出力:

```
[1, 2, 3]  
[1, 2]  
[1]
```



__環境情報:__

```
rustc 1.83.0 (90b35a623 2024-11-26)
```
自分用C言語学習 ～配列～

# 配列
同じ型のデータをまとめて保存できる箱(変数の集まり)
### 配列の宣言
```c:main.c
// フォーマット
型名 配列名[要素数];

// 例
int scores[3];
```
### 配列に値を入れる
```c:main.c
int main() {

    int scores[3];

    // 値を入れる
    scores[0] = 80;
    scores[1] = 90;
    scores[2] = 70;

    .
    .
    .

    return 0;
}

```
##### javaとCとで異なる点
・配列の宣言
・配列の長さを知る方法
```java:main.java
// 配列の宣言
int a[] = new int[〇];

// 配列の長さを知る方法(配列変数.lengthで簡単に取れる)
a.length
```
```c:main.c
// 配列の宣言
int a[〇];

// 配列の長さを知る方法はない
✕
```
# 添え字
```c:main.c
d[0]
d[1]
d[2]

// この時の0, 1, 2が添え字
```
# 多次元配列
```c:main.c
int a[3][4];

// 前の添え字が縦の範囲を表す
// 横の添え字が横の範囲を表す
```
Google Prompting Essentialsまとめ 　生成AIから望む結果を得るためのプロンプト。

## はじめに
ChatGPTやGeminiといった生成AIが急速に普及する中、「プロンプト（指示文）の書き方」はもはや新たなリテラシーの一つとなっています。
しかし、「AIにどう指示を与えれば自分の望む結果を得られるか」は実際にAIを活用していく中で模索している人が大半ではないでしょうか。

そんな中、Googleが提供する[Google Prompting Essentials](https://grow.google/intl/ALL_jp/prompting-essentials/)という生成AIとの対話をより効果的に行うための基本原則をまとめたガイドがあるのですが、今回キャンペーンで無料受講する事が出来たので要点をまとめてみました。

本記事では「具体的なプロンプトの構成手法」と「生成AIの特徴を利用したテクニック」の2構成でお伝えしていきます。
この記事が普段のAI活用の手助けになれば幸いです。

:::note info
※Google Prompting Essentialsの実際のコースでは上記の内容を全て包括して解説しているので、この2構成でのまとめには違和感を覚える方もいらっしゃるかもしれません。
あくまで、コース内容を理解しやすいように筆者が分類しているに過ぎないのでその点はご了承ください。
:::

## 具体的なプロンプトの構成手法

**①「タスク」　"誰"からの立場で何をしてもらう？**

プロンプトの中核は、AIにどんな「作業」をしてほしいのかというタスクの明示です。
タスク設計の最大のポイントは"誰"の視点で作業を行うか。つまりペルソナの指定です。
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
例：
「*あなたはプロのコピーライターです。*
 　スキンケア商品のキャッチコピーを50文字以内の箇条書きで出してください。」
  ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
  このようにプロのコピーライターというペルソナを指定する事で求めている回答の精度を高めています。
また、「出力の形式」を指定する事も最適な結果を求める上で重要な項目となっています。
箇条書き？表形式？50文字以内？など回答イメージに近づける情報は惜しみなく与えましょう。

このタスクに関する詳細情報に関しては、文量を気にせず、前提や背景、期待する出力のスタイルなど、細かく伝えるほど精度が上がるとされています。
<br>
**②「コンテキスト」　必要な背景情報を与える**
指定したタスクに関して、「どんな状況」で使うものなのかを明確にする事が大切です。
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
例：
「あなたはプロのコピーライターです。
  スキンケア商品のキャッチコピーを50文字以内の箇条書きで出してください。
夏に販売される予定の日焼けケアに焦点を当てたスキンケア商品です。
 営業会議で案の一つとして発表するのでキャッチコピーのターゲットも明確にして下さい」
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
 このように、出力された内容をどんな状況で利用するのか、また商品自体の詳細な情報を指定する事で出力の精度を高める事が出来ます。
 <br>

 **③「参照」　参考情報を与える**
関連するデータ・背景知識などを参照情報として提供すると、AIはより的確で一貫性のある出力ができます。
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
例：
「あなたはプロのコピーライターです。
  スキンケア商品のキャッチコピーを50文字以内の箇条書きで出してください。
夏に販売される予定の日焼けケアに焦点を当てたスキンケア商品です。
 営業会議で案の一つとして発表するのでキャッチコピーのターゲットも明確にして下さい。
 過去に採用されたキャッチコピーの例を以下に示します。
 A商品・・・・・　B商品・・・・・　C商品・・・・・・」
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
 注意点として、参考情報として与える情報は2～5つの参照数が適しているという事です。
 参考情報として例を挙げすぎると、結果の歪みやクリエイティビティに欠ける結果を出力する傾向が高くなります。

 ## 生成AIの特徴を利用したテクニック
 ここからは具体的なプロンプトの構成手法からは外れた、生成AIを実際に利用していく上で「望む結果」を得るためのテクニックとなります。普段AIを活用している方々にとっては当たり前に身についている内容かもしれません。
<br>
 **①「反復」　情報を追加しながら改善していく**
「望む結果」を得るためのプロンプトは必ずしも一発で完璧な出力をするとは限りません。
生成AIの特徴として、全体の関係性を把握して一度に解析するよりも、小さなタスクを繰り返し処理した上で解析する方が得意としています。

タスクを細かく細分化した上で、入力→出力を行い、その出力に対して新たなタスクを追加していく手法の方が望む結果が得られる可能性が高いという事です。
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
例：
「あなたはプロのコピーライターです。
夏に販売予定の日焼けケアに焦点を当てたスキンケア商品の特長を、箇条書きで3〜5個、簡潔に整理してください。」

→

「先ほどのスキンケア商品の特性を踏まえて、この商品に最も適しているターゲット層（性別、年齢層、悩み、生活スタイルなど）を明確に定義してください。
箇条書きでお願いします。」

→

「以下の条件で、スキンケア商品のキャッチコピー案を3つ作成してください：
・50文字以内
・箇条書きで
・定義したターゲットに響く言葉選び
・日焼けケアの効果を伝える
・夏の使用シーンがイメージできること」

→

「営業会議で共有する資料にふさわしい表現に調整してください。ビジネスパーソンが理解しやすく、商品価値が伝わるようなトーンでお願いします。」
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

このように段階的にタスクの入力を繰り返す事で、
・解析と出力の質向上　
・不明瞭な点を都度確認できるというメリット　があります。

また、場合によってはペルソナの視点を変えてみるという方法も有効です。
今回の例だと、「プロのコピーライター」の立場としてキャッチコピー案を作成していますが、実際に利用者側の立場で買いたい！と思いたくなる肌の悩み、商品の特性を導き出して、それを元にキャッチコピーを生成すればまた違った結果が得られるかもしれません。

## まとめ
プロンプトは単なる質問ではなく、AIとの協働を成功させるための設計図です。
今回紹介した以下の4つの視点を意識することで、出力の質は大きく変わります。

✅ タスクとペルソナを明確に

✅ コンテキストを具体的に

✅ 適切な参照を活用（参照数は2-5個の範囲）

✅ タスクを分割して反復して指示を与える
<br>

また生成AIに関する気になる事があれば記事にしていきたいと思います。
ここまで読んで頂きありがとうございました。
自分用C言語学習メモ ～最初の超基礎～

# Linux環境でのC学習 必要コマンド
しばらく触らなくなって忘れてしまったとき用のメモ
```terminal.bash
vi 〇〇.c
↑
viというエディタで〇〇.cという名前のC言語府ファイルを開く(新しくつくる)

cc 〇〇.c
↑
〇〇.cというC言語のソースコードをコンパイル(機械語に翻訳)する
※コンパイルが成功すると、自動的にa.outという実行ファイルが作られる。これが「実行できるプログラム」

./a.out
↑
コンパイルによってつくられたa.outを実行する
./ カレントディレクトリにあるという意味
a.out コンパイル後にできた実行ファイルのなまえ
```

※のちに「ファイル分割」に取り組むが、ファイル分割の際のコンパイルは複数まとめてやる
```terminal:bash
cc 〇〇.c ✕✕.c

./a.out
```



# if文の論理演算子
```c:main.c
// or 〇〇または××
||

// and 〇〇かつ××
&&

// not 〇〇ではない
!
// (!= → ≠)
```

# if文の基本的な形
```c:main.c
if (条件1) {

    // 条件が真の時実行される

} else if (条件2) {

    // 条件1はダメだったけど、条件2が真なら実行される

} else {

    // どの条件にも当てはまらなかったときに実行される
}
```

# ランダムに発生する乱数の作り方
```c:main.c
rand()%(最大値　-　最小値　+ 1) + 最小値
```

# 書式指定子
```c:main.c
%d // 整数(int)

%c // 文字(char)

%s // 文字列(char配列)

%f // 実数(少数)(float)

%.χf //小数点以下χ桁まで表示

%lf // 実数(double)

%u // 正の整数(unsigned int)

%p // ポインタのアドレス
```

# 繰り返し処理 ～for～
```c:main.c
for (初期化処理; 条件式; 増減) {

    // 繰り返したい処理
}
```
# 繰り返し処理 ～while～
```c:main.c
while (条件) {

    // 繰り返したい処理
}
```

# 繰り返し処理 ～do while～
```c:main.c
do {

    // 繰り返したい処理

} while (条件);
```
##### do whileの特徴
・まず中の処理を一回実行する
・実行した後で、条件をチェックする、条件が真ならまた繰り返す
・while文とは違って、「条件が最初にfalseでも、一回は実行される」

# 無限ループ
```c:main.c
// (1)とすることで一生真の値を出すことになり無限にループする
while (1) {

    // 処理;
    break; // breakで無限ループから抜けだす
}
```
breakは無限ループを抜けるための記述。基本的に、while文の中にif文を記述し、条件を満たすとき無限ループを抜ける処理を記述する。

### ループにおいてよく用いられるキーワード
```c:main.c
break 
// ループを「途中で終了する」
// 条件を満たしたときにループを抜けたいときに使用する

continue 
// 今回のループだけ「スキップして次へ進む」
// 特定の条件の時だけ処理を飛ばしたいときに使用する

return
// 関数の実行を即座に終了する(mainなら終了)
// 関数を抜けたいときに使用する
```

# 終わりに
javaと似てる部分も多く、すんなりいくことも多いが、若干異なる細かい仕様に頭が混乱する時がある。
どちらも楽しいのでこれから頑張ります！
ソースツリーでブランチを切ってリポジトリを管理する方法

# 新規ブランチを作成する方法
### 手順1:ローカルリポジトリの画面から新規ブランチを作成
![スクリーンショット (26).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943148/2adc4ef8-58f1-42fa-9f0c-1079e96950ad.png)
画面上部のバーにブランチという項目があるので、ダブルクリックでブランチのメニューを開き、新規ブランチを選択。
ブランチの名前を指定して、ブランチを作成をクリック。
※/を記述することで、階層構造を作ることができ、これはディレクトリとファイルのような関係となります。
### 手順2:画面左を見て、任意の位置にブランチが作成されていることを確認
![スクリーンショット (27).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943148/6aef623f-5f21-4ec3-876b-a89e69094bdc.png)

# ブランチのプッシュ方法

### 手順1:SorceTreeから作業したブランチをプッシュ
![スクリーンショット (28).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943148/6ec01c1d-3096-43c9-a5f0-773ef6ca84d6.png)
画面上部のメニューからプッシュをクリックし、プッシュしたいローカルブランチにチェックを付け、プッシュボタンをクリック。
### 手順2:webのgithubにログインしてBranchesをクリック
![スクリーンショット (32).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943148/5c6bb91c-7756-4984-9f96-2c869ca0ab34.png)
### 手順3:リモートにブランチが更新されていることを確認
![スクリーンショット (31).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943148/717bae1a-b581-4122-b0ab-aa4b00cf6e0e.png)
同名のブランチが更新されていることが確認出来たら成功。

### 以上
Quarkdown クイックスタートガイド

## Quarkdownとは

**Markdown with superpowers** - Markdownを大幅に拡張したスライド・文書作成ツールです。数式、グラフ、高度なレイアウトが簡単に作成できます。

## 前提条件

<blockquote class="twitter-tweet" data-media-max-width="800"><p lang="ja" dir="ltr">Markdownの進化系「quarkdown」使ってみる7⃣<br>サンプルのデモを手元でも動かせた！！！ <a href="https://t.co/fSvpuM2Rhe">https://t.co/fSvpuM2Rhe</a> <a href="https://t.co/CnyHz68DeA">pic.twitter.com/CnyHz68DeA</a></p>&mdash; Maki@Sunwood AI Labs. (@hAru_mAki_ch) <a href="https://twitter.com/hAru_mAki_ch/status/1931548957974634893?ref_src=twsrc%5Etfw">June 8, 2025</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

### Java環境の確認・インストール

Quarkdownを動作させるにはJavaが必要です。

```powershell
# Javaがインストールされているか確認
java -version
```

#### Javaがインストールされていない場合

1. **Oracle JDK（推奨）**
   - https://www.oracle.com/java/technologies/downloads/
   - Java 17以上をダウンロード・インストール

2. **OpenJDK（無料版）**
   - https://adoptium.net/
   - Eclipse Temurin（OpenJDK）をダウンロード・インストール

#### 環境変数の設定

```powershell
# システムのプロパティから設定
# Windows + R → sysdm.cpl → 詳細設定 → 環境変数
# JAVA_HOME: C:\Program Files\Java\jdk-17
# Path: %JAVA_HOME%\bin を追加
```

## インストール方法

### 1. Quarkdown実行ファイルのダウンロード

```powershell
# v1.3.3のzipファイルをダウンロード
# https://github.com/iamgio/quarkdown/releases/download/v1.3.3/quarkdown.zip

# 適切なディレクトリに解凍（例：C:\quarkdown）
# 環境変数PATHに C:\quarkdown\bin を追加
```


### 2. サンプルコードの取得

```powershell
# プロジェクト用ディレクトリに移動
cd C:\Prj

# GitHubからサンプルコードをクローン
git clone https://github.com/iamgio/quarkdown.git
```

## 動作確認

### インストール確認

```powershell
# 新しいPowerShellウィンドウを開いて確認
quarkdown --help
```

### サンプルスライドの実行

```powershell
# クローンしたサンプルディレクトリに移動
cd C:\Prj\quarkdown\demo

# デモスライドを実行
quarkdown c .\demo.qmd -p
```

成功すると、ブラウザが自動的に開いてスライドが表示されます。

### 基本コマンド

```powershell
# ヘルプの表示
quarkdown --help

# REPLモードで試す
quarkdown repl

# プロジェクト作成
quarkdown create my-project
```

## 最初のスライド作成

### 1. 新しいファイルの作成

任意のディレクトリで`.qmd`ファイルを作成します
（内容は`C:\Prj\quarkdown\demo\demo.qmd`を参考）

### 2. スライドのコンパイル

```powershell
# コンパイル＆ブラウザで表示
quarkdown c your-file.qmd -p

# ファイル変更を監視（リアルタイム更新）
quarkdown c your-file.qmd -p -w
```

## 基本的なファイル構造


### 新しいプロジェクトの構成

```
my-project\
├── main.qmd           # メインのスライドファイル
├── images\            # 画像ファイル
├── assets\            # その他のリソース
└── output\            # 生成されたファイル
```

### ファイル形式

- ファイル拡張子: `.qmd`
- 記法の詳細: 公式ドキュメントやデモファイルを参照

## コマンドリファレンス

### コンパイルオプション

```powershell
# 基本コンパイル
quarkdown c file.qmd

# プレビュー付き（ブラウザで自動表示）
quarkdown c file.qmd -p

# ライブプレビュー（ファイル監視）
quarkdown c file.qmd -p -w

# 出力ディレクトリ指定
quarkdown c file.qmd -o output-folder

# クリーンビルド
quarkdown c file.qmd --clean
```

### プロジェクト管理

```powershell
# 新しい作業ディレクトリを作成
mkdir my-presentation
cd my-presentation

# 新規プロジェクト作成（インタラクティブ）
quarkdown create .

# REPLモード（試行用）
quarkdown repl
```

## まとめ

Quarkdownは以下の手順で簡単に始められます：

1. **Java環境の準備**: Java 17以上をインストール
2. **実行ファイルの取得**: リリース版をダウンロードしてPATHに追加
3. **サンプルコードの取得**: GitHubからクローン
4. **動作確認**: デモスライドを実行
5. **作成開始**: 新しい`.qmd`ファイルを作成

記法の詳細は公式ドキュメントやサンプルファイルを参考にしてください。
【rails】DeviseのCookieやSessionの特性を理解する


## はじめに

こんにちは。アメリカ在住で独学エンジニアを目指している Taira です。
現在、Rails チュートリアルのアウトプットとしてアプリを製作しています。
認証機能に`devise`を導入してアプリ開発を進めていますが、ログインやログアウト後の挙動について、開発中に少し気になる動作があったので、今回は`devise`における**Cookie と Session の特性**について整理しておこうと思います。

---

## 結論：`devise`の基本挙動

- デフォルトでは「remember_me」を使わない限り、\*\*セッション Cookie（session-only cookie）\*\*が使用される
- この Cookie は**ブラウザを完全に終了するまで残り続ける**（タブを閉じただけでは削除されない）
- `dev`  コマンドを再起動してもセッションは残り続ける(タブを閉じたのと同じ挙動となる)
- `remember_me`を使用すると、**有効期限付きの永続 Cookie**が発行され、ブラウザを閉じてもログイン状態が保持される

---

## セッション Cookie と永続 Cookie の違い

| 種類            | セッション Cookie                | 永続 Cookie                        |
| --------------- | -------------------------------- | ---------------------------------- |
| 有効期限        | ブラウザ終了で削除               | `remember_for`（例：2 週間）で指定 |
| 保存先          | メモリ上                         | ディスク上（ブラウザに保持）       |
| 用途            | 通常ログイン時                   | `remember_me`を使ったログイン      |
| Devise での動作 | タブを閉じてもログイン状態は維持 | ブラウザを閉じてもログイン継続     |

---

## なぜ「dev 再起動後もログイン状態」になるのか？

開発中、`dev`コマンドを終了して再起動しただけなのにログイン状態が継続しているように見えることがあります。

- これは**ブラウザのプロセスが生きている＝セッション Cookie が保持されている**ためです
- `dev`（Rails サーバ）の停止とは無関係に、ブラウザ側が同じ Cookie を送り続けている状態です

---

## 本番環境でのセキュリティ懸念：公共 PC での利用

たとえば公共の PC などで、

1. ユーザー A がログインし
2. タブだけ閉じて PC を離れる
3. ユーザー B が同じブラウザを開いて再アクセスする

と、**ユーザー B が A のアカウントでアクセスできてしまう**可能性があります。

### 対策方法

#### 1. `remember_me`機能を無効化

- ビューからチェックボックスを削除
- コントローラで強制的に`params[:remember_me] = "0"`と設定

しかし、同様に UX を下げることにもつながります。サービスによって`remember_me`  を導入するか判断する必要があります。

#### 2. セッションの有効期限を短くする

```ruby
# config/initializers/session_store.rb
Rails.application.config.session_store :cookie_store, key: '_your_app_session', expire_after: 30.minutes
```

#### 3. ログアウト時にセッションを完全に削除

Devise は`destroy`時に`reset_session`を呼ぶため、明示的な操作は基本不要ですが、念のためログの確認をおすすめします。

#### 4. ユーザーに「ブラウザを閉じるように」注意喚起する

- 公共 PC では、タブを閉じるだけでは不十分なことを表示などで促す
- 例：「ご利用後は必ずブラウザ全体を終了してください」

---

## まとめ

| 想定シナリオ     | 推奨設定                                   |
| ---------------- | ------------------------------------------ |
| 公共 PC での利用 | `remember_me`無効 + セッション有効期限設定 |
| 自分の端末       | `remember_me`有効でも OK（注意喚起あり）   |

`devise`の Cookie や Session の挙動を理解することで、UX か**セキュリティリスク**のどちらを優先するか、サービスによって分けることができるようになります。