OmniAICreator/Qiita-1.07M huggingface dataset:
Ansible学習メモ⑤（Kubernetes関連）

業務で最近Ansibleを使い始めました。私自身はエンジニア職ではないので普段コーディングをほとんどしないです。少しAnsibleがわかるように学習し始めています。

### 1. Ansibleを使い、Kubernetes Namespace作成

以下のモジュールを使用：
kubernetes.core.k8s

まず、コレクションのインストール必要
```
ansible-galaxy collection install kubernetes.core
```
作成するマニフェストtest.yamlは以下のようです。

```
---
- name: create ns on kubernetes
  hosts: localhost
  gather_facts: false
  connection: local
  vars:
    project_name: "myapp"
  tasks:
    - name: create namespace
      kubernetes.core.k8s:
        api_version: v1
        kind: Namespace
        name: "{{ project_name }}"
        state: present
```
マニフェスト実行
```
ansible-playbook test.yaml
```


### 2. Ansibleを使い、Kubernetes Pod作成
以下のモジュールを使用：
kubernetes.core.k8s
まず、コレクションのインストール必要
```
ansible-galaxy collection install kubernetes.core
```
PodのYAML定義ファイルmypod.yamlは以下のようです。
```
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.21.6
    ports:
    - containerPort: 80
```
作成するマニフェストtest.yamlは以下のようです。

```
---
- name: k8s demo
  hosts: localhost
  gather_facts: false
  connection: local
  vars:
    myproject: "example"
  tasks:
    - name: create pod
      kubernetes.core.k8s:
        src: mypod.yaml
        namespace: "{{ myproject }}"
        state: present
```
マニフェストを実行
```
ansible-playbook test.yaml
```
Podだけではなくて、service, secret, Volume作成もすべて各リソースのYamlファイルを作成し、AnsibleのsrcパラメータにYamlファイルのパスを設定すれば、Ansibleを使い各リソースのデプロイが可能です。

### 3. Ansibleを使い、複数YAMLファイルを一括デプロイ
作成するマニフェストtest.yamlは以下のようです。

```
---
- name: k8s demo
  hosts: localhost
  gather_facts: false
  connection: local
  tasks:
    - name: Apply k8s resource
      kubernetes.core.k8s:
        definition: "{{ lookup('template', '{{ item }}') | from_yaml }}"
    　with_fileglob:
        - "./defs/mynamespace.yaml"
        - "./defs/mypod.yaml"
        - "./defs/myservice.yaml"
```
マニフェストを実行
```
ansible-playbook test.yaml
```



### 感想
個人的な感想ですが、KubernetesやOpenshiftにリソースをデプロイする際わざわざAnsible使用する必要がないかと思います。（便利性や効率性を感じていません）
個人開発で全国のタトゥーOK施設を探せるサービス『Tattoo Japan - タトゥージャパン』を作りました！

## 1. はじめに
こんにちは、FromScratchの石山です。
今回は、僕が個人開発しているWebサービス「Tattoo Japan - タトゥージャパン」について紹介したいと思います。

![img_433334_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4067328/a0367ef6-27ba-4af1-8e23-e09b2f39a4ba.png)



## 2. サービス概要

**Tattoo Japan（https://tattoo-ja.com）** は、日本全国の「タトゥーOKな温泉・銭湯・ホテル・プール・サウナ・タトゥースタジオ」などを検索・共有できるサービスです。

- タトゥーがある人が安心して行ける施設を探せる  
- 施設の情報はユーザーが自由に投稿・編集可能（Wikipediaのような仕組み）  
- 英語対応済みで、外国人観光客にも利用しやすい  
- OK/NG両方の施設情報を載せることでトラブルを防止  

## 3. なぜ作ったのか（動機）

僕自身タトゥーに対して偏見を持っていないし、好きなカルチャーでもあります。ただ、日本ではまだまだ「入れ墨＝反社会的」というイメージが根強く、温泉やサウナ、ジムなどで断られることもあります。

一方で、実際には「OKですよ」と明言してくれる施設も増えてきていて、もっとその情報が可視化されれば、タトゥーのある人が安心して過ごせる場所も広がるはず。

そんな思いからこのサービスを個人で立ち上げました。

## 4. 技術スタック

- フロントエンド：Next.js（App Router）
- ホスティング：Vercel（Proプラン）
- バックエンド：Supabase（Proプラン）
- その他：Tailwind CSS、React Hook Form、Zod など

インフラコストは月額で数千円〜1万円弱かかっていますが、なるべく高速かつ安定したUXを提供したくて、パフォーマンスには気を使っています。

## 5. 苦労したこと

- サービス開始初期はアクセスが全く無かったので、Instagramでの発信や、SEOを意識した記事構成に力を入れました。
- Wikipedia的に「誰でも編集できる」仕組みにしたことで、情報の信頼性を担保する難しさがあり、今は有料掲載プランやオーナー権限の導入を検討しています。

## 6. 今後の展望

- タトゥーOK施設の掲載数をもっと増やしたい
- インバウンド対応の強化（特に大阪万博に向けて）
- アプリ化・グッズ展開（Tシャツやステッカーなど）
- スポンサー広告や有料掲載などでの収益化

「偏見を変える」ことを目的にするのではなく、「タトゥーがあっても快適に過ごせる場所を知る」ためのツールとして、少しでも誰かの役に立てたらと思っています。

## 7. 最後に

ここまで読んでいただきありがとうございました！

「Tattoo Japan」はこちら👇  
🔗 [https://tattoo-ja.com](https://tattoo-ja.com)

SNSやブログなどで紹介していただけると泣いて喜びます🙏
firebaseでアップデートが必要と言われる。Firebase CLI v14.2.0 is incompatible with Node.js v18.16.0 Please upgrade Node.js to version >=20.0.0 || >=22.0.0

# はじめに
firebaseにアプリを ```deploy``` しようとすると、Node.jsのバージョンと互換性がないといわれたのでNode.jsをアップデートし互換性を解決するまでの過程を共有します。

■環境
Linux

# 問題
```firebase login``` を実行すると下記のようなエラー出ます。
```
Firebase CLI v14.2.0 is incompatible with Node.js v18.16.0 Please upgrade Node.js to version >=20.0.0 || >=22.0.0
```

Firebase CLI v14.2.0 は、Node.js v18.16.0 と互換性がないため、Firebase CLIのバージョンアップ、またはNode.jsのバージョンアップが必要です。と指摘されています。

Node.js(ver.20.0.0以上またはver.22.0.0以上)にしてくださいと書いてあるので、バージョンアップしていきます。

# 解決方法
Node.js(ver.22.0.0)にアップデートします。

この機会に、nodebrewでnode.jsのバージョンを管理しようと思ったので今回はnodebrewを使用してバージョンアップをします
### Homebrew🍺を入れる
https://qiita.com/tetusan/items/f2ca37147aafe28f7884
を参考にしました。

まず、LinuxにHomebrewを入れていきます。
```
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```
https://docs.brew.sh/Homebrew-on-Linux に従いながら引き続き作業していきます。
以下を順番に実行します。
```
test -d ~/.linuxbrew && eval "$(~/.linuxbrew/bin/brew shellenv)"
test -d /home/linuxbrew/.linuxbrew && eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"
echo "eval \"\$($(brew --prefix)/bin/brew shellenv)\"" >> ~/.bashrc
```
```
#Homebrewが入っている確認
brew install hello
```
これでLinuxにHomebrew🍺を入れることが出来ました！

### nodebrewを入れる
■インストール
```
brew install nodebrew
```
■確認
```
# バージョンが確認できればOK
nodebrew -v
```
■環境変数を追加する
```vi ~/.bash_profile``` で、以下を追加する。
```
export PATH=$HOME/.nodebrew/current/bin:$PATH
```
```:wq``` でvimを保存して終了。※キーボード入力してください。

```bash_profile``` を更新して設定を反映させます。
```
source ~/.bash_profile
```
セットアップ。これやらないとインストールできません。
```
nodebrew setup
```

### バージョンを指定してNode.jsをインストールする
■インストール可能なバージョンを確認します。
```
nodebrew ls-remote
```
■nodeのインストール※今回はver.22.0.0をインストールします。
```
nodebrew install-binary v.22.0.0
```
■インストールしたバージョンを確認します。
```
nodebrew ls
```

■使いたいバージョンを指定します。
```
nodebrew use v22.0.0
```
もう一度 ```nodebrew ls``` を叩いて、currentが指定されてればOKです。

最後に
```node -v``` でバージョンが表示されれば完璧です！！

### firebaseにログインする
そして``` firebase login``` を実行すると、、
``` ? Allow Firebase to collect CLI and Emulator Suite usage and error reporting information? Yes```と出てきました。成功です！

# おわりに
最初に直でアップデートしようとして、失敗しました。
これからはnodebrewで管理できると思うと楽です（笑）

# 参考
https://qiita.com/mame_daifuku/items/373daf5f49ee585ea498
https://qiita.com/tetusan/items/f2ca37147aafe28f7884
https://docs.brew.sh/Homebrew-on-Linux
Insights from a PhD in Databases: What Time Taught Me About Building Infra

![What Time Taught Me About Building Infra](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4034990/cb0145fa-cf82-4892-980b-92acd663fea6.png)

This month (April 2025) marks 4 years and 1 month since I started building [RisingWave](https://risingwave.com/).

![GitHub: https://github.com/risingwavelabs/risingwave](https://miro.medium.com/v2/resize:fit:1400/0*SeQK72xgkZYYGu5I.png)

Hard to believe we not only survived — but actually thrived — growing faster than we expected every single month. Sustaining high growth is never easy for a data infra company, especially during the peak of AI hype. That’s something I’ve never taken for granted. Looking back, here are a few lessons time has taught me.

## **Make friends with time**

Building data infra is brutal. No matter how hard you work, the first few years feel like shouting into the void. People don’t trust you — not because you’re wrong, but because you’re “too early.” But if time is on your side, and you believe in what you’re building, *stay the course*.

When we started RisingWave, our core principle was clear: *democratize stream processing with Postgres compatibility and S3 as the primary storage*. Four years later, I still believe this design will stand the test of time.

And above all, cherish every customer who trusted you before it was obvious.

## **Be water**

Adapt.

When the AI boom hit, we took a hard look at everything: Is data infra still something the market needs? Should we pivot to AI — chatbots, agents, the works?

Our answer: we’re proud to be a data infra company. But that didn’t mean standing still.

We tore down our GTM motion and rebuilt it from scratch. No more Google ads. Instead, we embedded AI in our marketing and sales workflows. We bet on high-quality content and GitHub presence. If we had kept chasing growth the traditional way, our ROI would’ve collapsed.

## **Ride the wave**

Every few months, I ask myself: what’s next — 3 months, 6 months, a year out?

Two years ago, the answer was simple: *be the best stream processing engine*. I think we’ve done that.

But the game changed. Iceberg has become the default table format. Everyone wants to build an Iceberg-based lakehouse — so we went all-in.

We’re not building a monolithic, all-in-one lakehouse. We bet on openness. Our job is to help users lower the bar for building their own lakehouse. We handle ingestion, transformation, and storage optimization — users bring whatever query engine they like.

Today, Iceberg is RisingWave’s #1 data destination — and our visibility is growing fast because of it.

## Conclusion

Looking back, I feel lucky. But luck doesn’t show up unless you stick around, stay consistent, and stay open to change.

So if you’re building data infra — or stuck in an AI anxiety spiral in 2025 — don’t panic.

Stay long-term. Stay flexible. Ride the wave.
ModelAttributeしてるのにThymeleafでないって言われた時

## @PostMappingでちゃんと@ModelAttribute/model.addAttributeしてるのに！！
それ、間違いです。GetMappingの役割がわかれば一瞬です(わからなかった側の人間直で2時間苦戦していました)

### GetMappingの役割

#### 1.ビューに初期データを渡すため
ここで@ModelAttributeを使うことで、GETリクエスト時にフォームオブジェクトをビューに渡すことができます。

#### 2.フォームデータのバインディング
@ModelAttributeは、フォームから送信されたデータをオブジェクトにバインドする役割も持っています。@PostMappingでフォームを送信するとき、@ModelAttributeは送信されたデータを受け取って、フォームオブジェクトにマッピングします。

#### 3.GETリクエストでフォームオブジェクトをモデルにセット
@GetMappingで@ModelAttributeを使う理由は、フォームが初期表示される際に、空のまたはデフォルトの状態でフォームオブジェクトをビューに渡すためです。これにより、ユーザーが入力するフォームフィールドを提供できます。

### というわけで
```java:controller
    @GetMapping("/menu")
    public String view(@ModelAttribute("SearchForm") SearchForm form,
                       @ModelAttribute("InputTrackInfoForm") InputTrackInfoForm inputForm,
                       Model model) {
```
こんな感じにつかってあげましょう
【JQuery】メソッドは文字列に機能しないこと

**背景**
HTML要素を文字列`htmlString`として取得し、`querySelectorAll`を使おうとすると、うまくいかなかった。
**原因**
querySelectorAll()などのメソッドはHTMLに対して機能するが、HTML文字列に対して直接使うことはできない。
HTML文字列に対してquerySelectorAllを使用したい場合は、まず以下のように文字列をDOMに変換する必要がある。

```javascript
//HTML文字列をDOMに変換
const parser = new DOMParser();
const doc = parser.parseFromString(htmlString, 'text/html');

//変換したDOMに対してquerySelectorAllを使用、例えば「tr」
const trElements = doc.querySelectorAll('tr');

//filterなどを使用
const filteredTrs = [...trElements].filter(tr => /*条件*/);
```
EKSのNodeが突然消えた時の原因調査と監視対策メモ

# EKSのノードが突然消えたときの原因調査と監視対策メモ

本番環境でEKSを運用していると、  
**「Auto Scaling GroupにはEC2が存在しているのに、`kubectl get nodes`に表示されない」**  
という現象に突如直面することがあります。

ここでは、その原因と、再発防止のための監視方法をまとめています。

---

## 現象の概要

- `kubectl get nodes` の結果にノードが表示されない  
- `kubectl get pods` の出力で、Podが `Pending` のまま進まない  
- Auto Scaling Group (ASG) には正常な状態のEC2インスタンスが存在する

---

## よくある原因と対処ミス

### 1. kubelet の起動失敗

- 以下のログで原因を確認する：
  - `/var/log/messages`
  - `/var/log/user-data.log`
  - `journalctl -u kubelet`
- 主な原因：
  - `bootstrap.sh` の実行失敗
  - ネットワークの不具合
  - TLS証明書エラーなど

### 2. IAM Role に必要な権限が不足

- ノードのIAMロールに以下のポリシーが必要：
  - `AmazonEKSWorkerNodePolicy`
  - `AmazonEKS_CNI_Policy`
  - `AmazonEC2ContainerRegistryReadOnly`
- これらが欠けていると、kubeletがEKS APIと通信できずノード登録に失敗

### 3. 古いノードの再起動による不一致

- 以前クラスタから削除したノードと同じ名前でEC2が起動すると、  
  EKS側では「すでに削除済みのノード」とみなされ、再登録されないことがある

---

## 実際に発生したときの対処法

- 該当のEC2インスタンスをASGから**デタッチ**して削除  
- ASGが新しいインスタンスを自動起動  
- 新しいノードがEKSに正常参加 → `kubectl get nodes` でReady確認

---

## 本番環境での予防策

### ☑ Auto Scaling Groupの`minSize`を1以上に設定

- 常に少なくとも1台のノードを維持するようにしておく

### ☑ Fargate profile を作成

- ラベルやネームスペースでPodをFargateへ振り分けることで、ノード依存を軽減

### ☑ EC2に監視スクリプトを配置

- 定期的に`curl`や`kubectl get nodes`を実行してクラスタの状態を確認

---

## 監視スクリプト例

### サイトの疎通確認

```bash
#!/bin/bash
URL="https://your-service.example.com"
STATUS=$(curl -s -o /dev/null -w "%{http_code}" $URL)

if [ "$STATUS" -ne 200 ]; then
  echo "$(date): Site unreachable! HTTP $STATUS" >> /var/log/eks-site-health.log
fi
```

### ノードのReady状態確認

```bash
#!/bin/bash
READY_NODES=$(kubectl get nodes --no-headers | grep -c " Ready")

if [ "$READY_NODES" -eq 0 ]; then
  echo "$(date): No ready nodes!!" >> /var/log/eks-nodes.log
fi
```

---

## まとめ

- **EC2インスタンスが存在していても、EKSがそれを「ノード」として認識しているかどうかが重要**
- 「ASGにはインスタンスがあるのに、ノードとして見えない」という状況は、  
  多くの場合 **kubeletの起動失敗** や **IAM設定ミス** が原因
- 発生したら該当インスタンスをASGから外してやり直すのが手っ取り早い
- 監視スクリプトを導入して、異常をすぐに検知できるようにしておく

---

ちなみに、  
**なぜかノードグループからインスタンスが勝手に外れることがある理由は、まだよくわかっていません……。**
オンプレミスからクラウドへ: なぜ移行とモダナイゼーションのためにLanding Zonesが必要なのか？

> 本記事は[こちらのブログ](https://www.alibabacloud.com/blog/from-on-prem-to-cloud-why-landing-zones-for-migration-%26-modernization_602143?spm=a2c65.11461433.0.0.4ee35355bu6s4v)を参考にしています。
> 翻訳にはアリババクラウドの[ModelStudio](https://www.alibabacloud.com/en/product/modelstudio)([Qwen](https://www.alibabacloud.com/en/solutions/generative-ai/qwen))を使用しております。

# クラウド移行の基盤としてのLanding Zone

今日のデジタル環境において、クラウド移行は非常に重要であり、組織はシームレスな移行方法を模索しています。ご存知の通り、クラウドへの移行には複数の複雑な課題が伴い、そのため明確な戦略を持つことが不可欠です。現在の環境に対する明確な理解、財務の概要、そして適切に定義された移行ロードマップは、成功する移行の主要な柱となります。しかし、クラウドベースのワークロードやアプリケーションを構築し展開するためには、組織には安全かつコンプライアンスに準拠した基盤が必要です。したがって、Landing Zone（ランディングゾーン）の設定は、クラウド環境を効果的に設定および保護するために非常に重要です。Landing Zoneは、組織のクラウドインフラストラクチャの集中管理環境であり、すべてのクラウドイニシアチブの出発点となる基盤です。これは、安全でスケーラブルなクラウドインフラストラクチャの展開における長年の経験をもとに構築されており、どのクラウドプロバイダでもプロビジョニングできます。[Alibaba Cloud Landing Zone](https://www.alibabacloud.com/solutions/landing-zone) は、顧客がAlibaba Cloudでの取り組みを便利かつ構造的な方法で開始できるように設計されています。Alibaba Cloud Landing Zoneは、アカウント管理、リソース管理、ネットワーク計画、財務管理、コンプライアンス監査、セキュリティなどをカバーする、クラウドベースのアーキテクチャブループリントとガバナンスソリューションを企業に提供します。Landing Zoneサービスは、顧客がクラウド上でITランドスケープを設計・管理し、カスタマイズされたクラウドソリューションを活用できるよう支援します。これは、ビジネスが迅速にクラウド環境をセットアップできる自動化され、安全なアーキテクチャです。これにより、組織は安全かつコンプライアンスに準拠し、コスト効率の高い方法でワークロードをAlibaba Cloudに効果的に移行できます。一貫したフレームワークと多くの利点により、クラウド移行を合理化できます。また、進捗を評価し、移行の成功を戦略化するための青写真としても機能します。Landing Zoneがあれば、移行の旅をスムーズに進めることができ、意図したクラウド環境から多くの利点を得ることができます。[Alibaba CloudのLanding Zone](https://www.alibabacloud.com/solutions/landing-zone)はクラウド移行を加速させます。広範な設定を行うことなくインフラを迅速にセットアップできるため、初期費用を削減するのに役立ちます。より良いコスト最適化のために戦略を立て、最新の安全性とコンプライアンス基準を満たす安全なアーキテクチャを手に入れ、クラウド環境上にアプリケーションやサービスを安全に展開することができます。

## クラウドLanding Zoneを持つことの利点
[Landing Zone](https://www.alibabacloud.com/solutions/landing-zone)は、企業のコンプライアンスを強化し、セキュリティを向上させます。手動設定の必要性を排除し、組織が新しい製品を市場に迅速に投入することを可能にします。ネットワーク設定、ファイアウォールなどを一箇所で設定できるため、ネットワーク面での時間を節約します。Click2Cloudでは、当社のクライアントのためにAlibaba Cloud Landing Zoneを実装しました。私たちは、オンプレミスインフラ、アプリケーション、データベースを移行またはモダナイズしたいかどうかにかかわらず、お客様がクラウドの旅の一歩を踏み出すお手伝いをします。

## 結論
十分に設計されたLanding Zoneは、成功し安全な[クラウド移行](https://www.alibabacloud.com/solutions/cloud-migration)の礎です。Click2Cloudの専門知識を活かしてAlibaba CloudのLanding Zoneを利用することで、組織は自信を持ってデジタルトランスフォーメーションの旅を加速させることができます。手動作業の削減からコンプライアンスとセキュリティの確保まで、カスタマイズされたLanding Zoneは、クラウドでスケールし、革新し、成長するための基本的なフレームワークを提供します。

免責事項: 本稿で表明された見解は参考用であり、必ずしもAlibaba Cloudの公式見解を表すものではありません。
【HTML&CSS】z-index=-1に設定されたボタンがクリックできない

**背景**
ボタン要素にz-index=-1を設定しました。
完全にz-index=0の要素の下で隠れているようにしていないのに、
クリックできない。

**理由**
z-index=-1を設定すると、その要素は通常のフロー（z-index=0と同等）よりも下に配置される。
↓
親要素や他の要素（背景を含む）がその上に重なると、ボタンへのクリックイベントがブロックされる。
↓
マウスイベントは最前面の要素から順に伝搬するため、上に重なった要素がクリックを「キャッチ」してしまう。

**解決策**
z-indexを0以上の値に設定し、ほかの方法で位置調整をする。
【ChatGPT＋4o Image Generation】で、黄ばみをなんとかしたい。


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

　今回は、4o Image Generationで起こる、黄ばみをなんとかしたい。

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

　文化庁レポートをもとにした
　　著作権法についての動画（約20分）
　　　[かいちのAI大学　【警告】ChatGPTの画像生成は危険です...【4o Image Generation】](https://youtu.be/8VLUnG-iyo0?si=rAfjMboqmNqppDGq)
***
　では、さっそく【本題】です。

　今回は、
　　4o Image Generationで発生する
　　　黄ばみをなんとかしたいです。

　4o Image Generationでは、
　　ふつうに生成すると、
　　　黄ばみというかセピア色に
　　　　なりやすいですよね。

　それなのに
　　海外からは、
　　　それらしい文句が
　　　　出ていません。

　出ているのは
　　ほぼ日本だけ。

　よくよく調べたら
　　少しあるみたいでした😅
　　　それでも少ない。

　こちらのnoteの記事に
　　筆者の感覚や過去の経験から
　　　黄ばみのことを書いています。
　　　　[note　黄ばみの標準──青い目の世界と、黒い目の視覚感覚](https://note.com/akikito/n/nc79e57d06634?sub_rt=share_pb)
　　　　　ちなみにこちらは
　　　　　　最後まで読もうと
　　　　　　　思ったら、有料です😅

　詳しくは、
　　この記事に譲ります。

　どうやら
　　こうした黄ばみは
　　　海外の人には、高級感と
　　　　捉えられるのだそうです。

　その意識が、
　　そのまま、画像生成にも
　　　無意識に取り込まれている
　　　　のだとか。

　確証はありませんが、
　　OpenAIがこの問題に着手しており
　　　そのうちに提供される、とか。

　まぁ、そうだとしても
　　発表があるとは思えませんね。
　　　DALL-E3もそうでしたし。
***
　さて、
　　それはそれとして、
　　　実際問題、日本人としては
　　　　この黄ばみ問題は
　　　　　**明らかになんとかしたい**
　　　　　　問題です。よね😅

　では、どうすべきか。

　方法としては、
　　いくつかあります。

　簡単に言うと、
　　“Promptに追記する”方法の
　　　一択です。

　挙げてみましょう。

「no yellow tint, no warm filter」を追記
　[ひよどりさんポスト](https://x.com/hiyodorixxxx/status/1908325614043750583?t=5bE88n_JJejWauawVqoI2g&s=03)


「ビビッドでクリアな色調」を追記
　[まゆひらaさんポスト](https://x.com/riddi0908/status/1913296784274936082?t=t7pLQi_SMuKU72qbRHsrYg&s=03)


「no sepia」などのプロンプトでニュートラルな色調に調整
　[muuさんポスト](https://x.com/muumuunimuu/status/1913511875121406118?t=D0iRJ0-v9patvYoQ08__jw&s=03)


末尾に「Apply neutral white balance. Avoid all yellow tints, warm filters, and sepia tones. Use daylight-style」を追記
　[あおい整備兵さんポスト](https://x.com/panzer343343/status/1913030177657147536?t=6bLwXWj7Akve6hClMVVPBQ&s=03)

***
　私はこちらを使っています。


```Text:ケルビン値Prompt
ニュートラルな昼光（約5500K）のホワイトバランスにして下さい。
```
　　[AI FREAKさんポスト](https://x.com/AiFreak_tool/status/1913740120701997451?t=DFkbahP2W_PobLUFO9fppQ&s=19)

![20250421_001120.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457238/4209b6ba-a199-4ce5-a930-d8df4a1f2135.jpeg)

　　この画像は下記から拝借。
　　　[Kyutaroさんポスト](https://x.com/kyutaro15/status/1913750605816017202?t=FmyyZ2dri30fGGri61skpg&s=19)

　私がこれを使う理由は
　　数値を変えれば
　　　雰囲気を調整可能だから、です。

　どれを使うかは
　　みなさん次第です。

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

　今回は、ここまで。
💥直したって何をよ？地獄コミットメッセ問題、ギャルがConventional Commitsで救う🌈

# fix: 直したって何をよ？地獄コミットメッセ問題、ギャルがConventional Commitsで救う🌈

> **この記事では、gitのコミットメッセージにありがちな失敗例と、Conventional Commitsのルールに基づいた書き方を、ギャル風にやさしく解説しちゃうよ💅✨**
> 
> 「fix: 修正」だけじゃ伝わらないってば！**未来の自分もチームも笑顔になれるコミットメッセのコツ**、ぜ〜んぶ教えちゃう💖

---

## 🌀 コミットメッセージ失敗例｜地獄のログにしないために

ある日チームのGitログ見て、マジで震えたんだけど…

```bash
fix: 修正
update: test
change: 少し変更
aaa
test
やばい
no message
修正2
バグじゃなかったわ
コミットできた〜！！
```

🙄 **なにを直した？どこで？なんのために？意味不明すぎてヤバ〜！**

Gitログって未来の自分とか他の開発者に向けたラブレター💌なのに、
このままだと**「謎ポエム」か「黒歴史日記」**じゃん！？

> **Gitはドキュメント！メッセージは未来のあたしへのラブコール💘**

---

## ✅ gitで使えるコミットメッセの書き方（Conventional Commitsってやつ✍️）

以下のルール守るだけで、
**検索しやすくて分かりやすい、チームに超優しいログ**が爆誕しちゃうの🌟

```text
<type>(scope): なにしたか

* 補足（必要ならね）
* チケットのURLとかIDとか
```

### 例：

```text
fix(auth): JWTの期限切れチェック修正💫

* LocalDateTimeの比較を統一✨
* トークンの有効期限処理を見直したよん

チケット: #1234
```

---

## ✍️ よく使うConventional Commitsのタイプ一覧だお💖

| type        | 内容                         | 例                        |
|-------------|------------------------------|----------------------------|
| `feat`      | 新機能の追加                 | 検索機能追加など✨         |
| `fix`       | バグ修正                     | ログイン時のクラッシュ修正とか💥 |
| `docs`      | ドキュメント変更            | README更新〜📄             |
| `style`     | 見た目だけの変更             | Lint対応とかね🌈            |
| `refactor`  | 振る舞いは変えない中身改善   | 命名変更・関数分割など💡    |
| `test`      | テスト関係                  | 単体テスト追加しといたよ🧪 |
| `chore`     | その他の雑務                 | 依存パッケージ更新とか🛠️    |

> 💡 **VSCode拡張とかcommitlintとか使えば、ルールもバッチリ守れるよ💻💅**

---

## 💬 コミットメッセージの書き方Tips（ギャルの極意）

- **1コミット1トピックが鉄則！**「ついでに」はNGだよ〜🙅‍♀️
- **改行とか箇条書きで読みやすく！**見た目大事っしょ？
- **スコープ（どこ修正したか）書くと超助かる💘**
- **なんでその修正したのか**も書いてくれると未来のあたしが泣いて喜ぶ😭

---

## 🎯 実務で使えるイケてるコミットメッセージ例💖

```text
feat(uploader): 健診CSVアップロード機能つけたった✌️

* 一時保存処理入れた〜
* StorageServiceにアップ処理書いた✨
* エラハン仮対応してあるから見といて！

チケット: #5678
```

```text
fix(path): Windowsでパス崩壊するバグ潰した💥

* 区切り記号の重複なくしたよ！
* Paths.get()に揃えた〜

チケット: #7890
```

```text
docs(readme): セットアップ手順追加したよん📝

* 初期構築方法書いたよ〜！
* 環境変数のとこ補足したっちゃ〜

チケット: #1357
```

---

## 😱 ダメコミットあるある集

| メッセージ         | ツッコミ              |
|--------------------|-------------------------|
| `aaa`              | 何それ？サウンド？🎶    |
| `やばい`           | お前がやばい😇           |
| `修正2`            | 修正1どこに落とした！？  |
| `バグじゃなかったわ` | 戻してこいや〜！🌀       |
| `no message`       | マジで無！闇〜🖤         |

---

## 🛠 開発効率爆上がりツール一覧🧰

- [VSCode拡張: Conventional Commits](https://marketplace.visualstudio.com/items?itemName=vivaxy.vscode-conventional-commits) ★GUI楽でオススメ！
- [commitlint](https://commitlint.js.org/) + [husky](https://typicode.github.io/husky) でチェックもバッチリ✔️
- [Cursor](https://www.cursor.so/) でAIちゃんにアシストしてもらお💕

---

## 🎤 まとめ：良いコミットメッセは未来の自分を救う✨

ちょっとした気遣いで、
**開発スピードもレビュー効率も、Gitログの神っぽさ**もぜんぶ爆上がり💥

みんなでConventional Commits使えば、
**Gitが史上最強の開発ドキュメントになるってば📚✨**

---

## 📣 あとがき：PLやってるギャルからひとこと💄

いまPLとして、要件定義〜保守まで全部ガッツリ関わってるけどさ、
**ログがちゃんとしてるだけで、プロジェクトのストレス爆減するってマジで体感してる✌️**

**この記事いいじゃんって思ったら、LGTM・シェア・コメントで推して〜🙏💋**

「ギャル風の技術記事もっと読みたい！」って声も待ってるよん🌈

ちなこれ次回の記事！
[なんでConventional Commitsってそんなに大事なの？Git履歴は“構造”なのよねって話🌈](https://qiita.com/doruboxshiki/items/6f0777daf05215f154ab)
【PHP】parsererror SyntaxError: Unexpected end of JSON inputというエラーが出た

**背景**
DBで保存したデータをフロント側で表示させたいが、
データはフロント側にうまく出てこないし、下記のエラーが出た。
``parsererror SyntaxError: Unexpected end of JSON input``

そもそもバック側からのレスポンスが届いた？と思って、functionを簡素化してテストしてみた。
フロント側：
```javascript
$.ajax({
            url: "https://example.com/example/function/function.php",
            type: "POST",
            data: data,
            dataType: "json",
            success: function(response) {
                if (response.success) {
                    console.log(response.message);
                } else {
                    console.log(response.message);
                }
            },
            error: function(xhr, status, error) {
                console.log("AJAXエラー: ", xhr, status, error);
            }
        });

```
バック側：
```PHP
header('Content-Type: application/json'); //レスポンスをJSONとして送信
function example(){
    echo json_encode(['success' => true, 'message' => 'ok']);
}
```
``parsererror SyntaxError: Unexpected end of JSON input``が出た。

parsererror SyntaxError: Unexpected end of JSON input というエラーが出る理由は、サーバーから返ってくるレスポンスが JSON 形式になっていない、または空になっている可能性が高い。

**エラーの原因**
example()の出力の前に余計な出力がある
もしexample()を定義しているファイルや、それを呼び出すPHPファイルに空白、改行、エラーメッセージ、HTMLタグなどが含まれていると、出力が純粋な JSON ではなくなる。

**解決策**
最初にob_start()、最後にob_end_clean()を追加し、意図しない出力を防ぐ。

```PHP
function example(){
    ob_start(); //出力バッファリングを開始
    echo json_encode(['success' => true, 'message' => 'ok']);
    ob_end_flush(); //バッファをフラッシュして送信
    exit();
}
```
``parsererror SyntaxError: Unexpected end of JSON input``がなくなり、データもフロント側に出た。
【ネットワーク】ARP (Address Resolution Protocol)

# はじめに

こんにちは。アメリカに住みながら、独学でエンジニアを目指しているTairaです。
今回は、コンピュータネットワークの基礎として欠かせない「ARP（Address Resolution Protocol）」について解説します。


## ARPとは？

ARPとは、「**IPアドレスからMACアドレスを取得するためのプロトコル**」です。
通信相手のIPアドレスは分かっていても、実際にイーサネットなどのデータリンク層で通信を行うには、MACアドレスが必要です。
そのため、ARPを使って「このIPアドレスを持っている機器のMACアドレスは何か？」を調べます。

---

## ARPの仕組み

### 1. ARPリクエストの送信
送信元の機器が「このIPアドレスのMACアドレスを教えてください」とネットワーク上にブロードキャスト（LAN内の全員に）を送信します。

### 2. ARPリプライの受信
該当するIPアドレスを持つ機器が、自分のMACアドレスを送信元に返します（ユニキャスト）。

### 3. ARPキャッシュへの保存
得られたIPとMACの対応情報はARPテーブル（キャッシュ）に一時保存され、次回以降の通信ではARPリクエストなしで通信できます。

---

## ARPが使用される範囲：LAN内

ARPは主に**同じLAN（ローカルエリアネットワーク）内**で使用されます。
なぜなら、MACアドレスはLAN内でのみ意味を持つ情報だからです。

### ● 同じLAN内の通信例
- PC（192.168.1.2） → プリンタ（192.168.1.10）
- スマホ → NAS（ネットワークストレージ）

### ● LAN外との通信では？
LAN外の機器に通信する場合（例：インターネット）は、まずルーターのMACアドレスをARPで取得し、そのルーターにデータを中継してもらいます。宛先が外部でも、**ARPの対象は“次の機器（ルーター）”**です。

---

## ARPで使われるのはプライベートIPアドレス

ARPでやり取りされるIPアドレスは、**プライベートIPアドレス**です。
家庭やオフィスのLAN内では、以下のようなプライベートIPが使われます。

- 192.168.0.0 ～ 192.168.255.255
- 10.0.0.0 ～ 10.255.255.255
- 172.16.0.0 ～ 172.31.255.255

これらのアドレス空間でMACアドレスを解決するためにARPが使われます。

---

## ARPの使用例：Linux/macOSでの確認

ターミナルで以下のコマンドを実行すると、現在のARPテーブルを確認できます。

```bash
arp -a
```

---

## 補足：ARPと他のプロトコルとの関係

- **DHCP**：IPアドレスを自動で割り振る仕組み（ARPとは役割が異なる）
- **NAPT**：複数の機器のプライベートIPを1つのグローバルIPに変換（ARPはLAN内の通信の準備）
- **mDNS**：LAN内で名前（host.localなど）をIPアドレスに解決する仕組み（ARPはIP→MAC）

---

## まとめ

- ARPは「IPアドレスからMACアドレスを取得する」ためのプロトコル。
- 主にLAN内で使用され、プライベートIPに対してMACアドレスを解決する。
- 実際の通信はMACアドレスを使って行われるため、ARPによる事前解決が必須。
- LAN外との通信でも、ルーターのMACアドレスを調べるためにARPは使われる。
AWS認定デベロッパーアソシエイト合格記

書くネタがなさ過ぎたのでAWSデベロッパーアソシエイトの合格までの
勉強方法などをつらつらと書いていきます。

今回取得した資格は[AWS 認定デベロッパー – アソシエイト](https://aws.amazon.com/jp/certification/certified-developer-associate/)です。

### 取得前の経験とかはこんな感じ
作ったことはないけど大体の機能は分かってるつもり(作れるとは言ってない)

* AWSは仕事で触れることはあるがインフラ部分がメイン
* APIゲートウェイ作ったことない
* Lambdaはなんとなくわかるけど関数とかは作ったことないし作れる気はしない
* AWSのアソシエイト資格は[ソリューションアーキテクト](https://aws.amazon.com/jp/certification/certified-solutions-architect-associate/?ch=sec&sec=rmg&d=1)と[SysOpsAdministrator](https://aws.amazon.com/jp/certification/certified-sysops-admin-associate/)は取得済
* CFnはちょっとだけ経験あり
* CodePipeLine系もちょっとだけ触ったことある
* Gitとかプログラムとかはほぼ無し
* DBは作るだけあとはアプリ担当よろしくってレベル

### 勉強に使用したツール
会社がUdemy契約しているとかで実費０円で受講できたのでUdemyを使用しました。
* Udemyで資格取得用の動画視聴
* Udemyで資格取得用の模擬試験実施

### 勉強方法
これしかない
1. とりあえずぼーっと動画を視聴する　ここではそういう用語とかあるんだなーってくらい
1. 模擬試験を１回実施してみる　確実にわかるってところ以外はチェックを入れておく
1. 解説を見て内容を確認する　わからないままにしておかない　用語も覚える
1. 模擬試験をもう１回実施する　９割くらいの正答率を目指す
1. 次の模擬試験を実施する

２～５を模擬試験分ひたすらやる
私は大体６０時間くらいやったような気がします。
模擬試験全５問を3週くらいしました。

### 気を付けたいポイント
* 同じ模擬試験を複数回やると暗記しちゃうので2,3日置いてからまたやる
* 問題の意図を確認する　ベストプラクティスを求めているのか費用対効果を求めているのか
* この用語がでたら大体答えはこうなるってのが何パターンか記憶できていると完璧
　DVAでよくあるのがSQSで重複したときにどうしたら良いかみたいな問題や
　DynamoDBでProvisionedThroughputExceededExceptionが出たときにどうするか等

### 試験当日(これが一番大事)
私はこれまで３回AWSのアソシエイト試験を受けてきましたが
毎回完璧だと思ったことはありません。
アソシエイトの試験では全65問の内15問はテストの配点にならない問題があるようで
実際試験を受けていると
　こんな用語初めて見るんだけど・・・
　全然何言ってるかわかんないよ・・・
みたいなトンデモ問題が出てきます。しょっぱなにこれが来ると萎えちゃうんですけど
見たことない問題は２択まで絞れるならラッキーくらいで次進みましょう。

あとは模擬試験の内容とちょっと違うような問題が出てくるはずなので
確実に正解していけるようにしておくことが大事だと思います。

ただ実際トンデモ問題15問全部わからん・・・ってところでメンタルブレイクしてくるので
ハイハイそういう事やってくるのね？って感じで予め認識しておくことが大事だと思います。

SAAがもうすぐ失効してしまう・・
SAPとるしかないか・・

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3857934/9ce6603f-dc77-4d82-99c1-0c2d73dd9c96.png)
Zodの omit で登録・編集フォームのバリデーションを分ける

## はじめに

`react-hook-form` と `Zod` を組み合わせたフォーム実装を行った際、登録時と更新時でバリデーションが必要な項目が異なるケースがありました。  
この記事では、そこでハマったポイントと解決策をまとめます。

## 問題の箇所

「新規登録画面」と「編集画面」で、共通のフォームを使っていました。  
ただし、**登録時**はユーザーID（`user_id`）の入力が必要ですが、**編集時**はユーザーIDを表示するだけで、編集できないようにしたいと考えていました。

最初は、新規登録用に作成した以下のスキーマを編集画面でも使い回そうとしました。

```tsx
export const userFormSchema = z.object({
  user_id: z
    .string()
    .nonempty('IDは必須です')
    .min(3, 'IDは3文字以上で入力してください')
    .regex(/^[a-zA-Z]+$/, 'IDは英単語のみ使用できます'),
  name: z
    .string()
    .nonempty('名前は必須です')
    .max(50, '名前は50文字以内で入力してください'),
  // ...他のフィールド
});

export type UserFormSchemaType = z.infer<typeof userFormSchema>;
```

ところが、編集画面では user_id フィールドをフォームに含めておらず、表示専用のため、`react-hook-form`が `handleSubmit()` 実行時に `user_id` のバリデーションでエラーとなり、フォームが送信できませんでした。

### 問題内容
- バリデーションエラーでフォームが送信できない
- `handleSubmit()`のコールバックが呼ばれない

## 解決方法

### Zodの`omit`メソッドを活用する

調査の結果、Zodには便利な`omit`メソッドがあることが分かりました。
これを使えば、既存のスキーマから特定のフィールドだけを除外したスキーマを簡単に作ることができます。

```tsx
// 登録用スキーマ（user_idを含む）
export const userFormSchema = z.object({
  user_id: z
    .string()
    .nonempty('IDは必須です')
    .min(3, 'IDは3文字以上で入力してください')
    .regex(/^[a-zA-Z]+$/, 'IDは英単語のみ使用できます'),
  name: z
    .string()
    .nonempty('名前は必須です')
    .max(50, '名前は50文字以内で入力してください'),
  // ...他のフィールド
});

// 🔵編集用スキーマ（user_idを除外）
export const userEditFormSchema = userFormSchema.omit({ user_id: true });

export type UserFormSchemaType = z.infer<typeof userFormSchema>;
export type UserEditFormSchemaType = z.infer<typeof userEditFormSchema>;
```

編集コンポーネントでは、`userEditFormSchema`と`UserEditFormSchemaType`を使用します。

```tsx
const {
  register,
  handleSubmit,
  control,
  setValue,
  formState: { errors },
} = useForm<UserEditFormSchemaType>({
  resolver: zodResolver(userEditFormSchema),
  defaultValues: {
    // user_idを削除
    name: '',
    description: '',
    // ...他のデフォルト値
  },
  mode: 'onChange',
});

// ...省略...

// 更新処理
const onUpdateUser = async (data: UserEditFormSchemaType) => {
  // ここでuser_idを追加
  const formData = {
    ...data,
    user_id: user?.user_id || '', 
    // ...他のデータ加工
  };

  // DBへの更新処理
  const result = await updateUser(formData);
  // ...省略...
};
```

:::note info
このように `omit` を使えば、共通したバリデーションルールを再定義する必要がなくなる上、バリデーションのルールを変更する時も１箇所で対応できます。
:::

## おわりに

フォームの一部のフィールドが異なるために、バリデーションスキーマを別で定義することは冗長のため避けたかったです。
そこで`Zod`の`omit`を活用すれば、スキーマを再利用できてスッキリした構成になるのでおすすめです。
他にもおすすめの対応方法があれば、是非教えてください！


## 参考サイト

https://zod.dev/?id=pickomit
OpenAI の Text to speech API を試してみた。

OpenAI から Text to speech API がリリースされていたので、試しに音声ファイルを出力してみました。

## コード

API キーは、OpenAI のアカウントで作成してください。
ChatGPT の API キーをお持ちの方は、まんま流用することもできます。

```
import openai

# OpenAI API キーを設定
openai.api_key = "<OpenAI API キー>"

# 音声生成リクエスト
response = openai.audio.speech.create(
	model = "tts-1",
	voice = "alloy",
	input = "Hello, how are you?"
)

# 音声ファイルとして保存
with open( "output.mp3", "wb" ) as file:
	file.write( response.content )
```

## パラメータ

* model
    * 音声合成モデル
        * "tts-1"
        * "tts-1-hd"
* voice
    * ボイス
        * 男性
            * "alloy"
            * "ash"
            * "echo"
            * "fable"
            * "onyx"
        * 女性
            * "coral"
            * "nova"
            * "sage"
            * "shimmer"
* input
    * 読み上げるテキスト
        * 日本語も[対応](https://platform.openai.com/docs/guides/text-to-speech#supported-languages)しているようです。


## 参考サイト

* 公式 Docs
    * https://platform.openai.com/docs/guides/text-to-speech

(2025/04 頃執筆)

---

株式会社ボトルキューブではお仕事を募集中です。
お問い合わせは下記リンク先のフォームからご連絡ください。
https://www.bottlecube.co.jp/contact
Microsoft AI Skills Fest で早速バウチャーGetしました！（2025/5/29まで）

## はじめに

今年もMicrosoft認定資格のバウチャーチケットが**無償**でもらえるイベントがやってきました。
以下のリンクからチャレンジに参加できますので、ぜひ皆様も挑戦してみてください！
（私はチャレンジ完了済で、先日バウチャーチケットも届きました）

https://learn.microsoft.com/ja-jp/training/topics/event-challenges/ai-skills-fest-challenge-official-rules

## 参加方法、コース一覧、バウチャー適用可能な資格一覧など

他の方がすでにまとめていましたので、こちらを引用させていただきます。

https://zenn.dev/banboobloom/articles/2025040500001

## 皆様が気になること

ここからは実体験をもとに皆様が気になるであろうことを書き残していきます。

### その１．応募フォームのMicrosoft Learnのユーザー名

応募フォームの項目１つ目にユーザー名を入力する箇所があります。
指示通り、リンクを開いてユーザー名を確認すると、
なんとほぼ情報が無い画面に数字8桁のコードのみ表示されます。

LastName FirstName じゃないんだ？と困惑されるかと思いますが、
数字8桁で大丈夫です。なぜなら私にはバウチャーチケットが届きましたので。フフフ…

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2258693/0f41b2d8-5565-47f7-9b4a-2bb52181afc8.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2258693/b8fec200-62d6-4726-85cf-06385eb3088c.png)


### その２．バウチャーチケットがもらえるタイミング

私の場合、4/10(木)にチャレンジ参加の登録をし、その日中にチャレンジを完了しました。
商品期間的には１つ目の期間に当てはまります。

そして4/19(土)に当選連絡が届きました。 
なので抽選と言いつつ、参加者が少ないうちは実質早い者勝ちなのかも？
と思っております。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2258693/ea4b962a-d74f-40d9-8213-2e9f98dc4e60.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2258693/0e402d1c-b9bb-43d1-951d-53ff8d6f9ee3.png)


## さいごに
チャレンジ期間は2025年5月28日午後11時59分PT、
つまり日本時間で**2025年5月29日(木)午後3時59分**までなので早めの実施をお勧めします～。
AIの進化でブログ(備忘録)に意味がなくなった

# LLPMの記事を書こうと思っていた
LLPMで本格的に多数接続を実装しようと思って調べていました。が、自分で調べるよりもNordic AIに聞いたほうが早いんですよ(笑)
もちろん情報の正確性はこれから検証する必要があるわけですが、少なくとも自分で調べる手間は格段に減りました。そもそもにおいて、これだけ短時間の間にソースを引き当てる自信はありません(笑)
# もう意味がなくなった
もちろんAIは最初の教師データとしてWebクロール(みたいなこと)をするので、Web上に何も情報が出てこなくなったら何もできないわけです。だから全員が一斉にWeb上で質問をしなくなったりWikipediaに何も書かなくなったりしたら崩壊してしまうわけですが、きっとそうはならないでしょう。
でももうここに記事を書く必要はほぼなくなったな、と実感した次第です。というか、何か疑問に思ったらまずchatGPTに聞きますからね。ブラウザで単語入力して調べないです、ええ。
# さて、どうする？GOする？
おそらくしばらくはAIにとりとめもなく聞いた話をまとめ、それが正しいかどうかを検証するという形で続くんじゃないかなと思います。そのあと少しして(以下略ｗ
単一責任の原則（SRP）におけるOOPとFPの比較

単一責任の原則（SRP: Single Responsibility Principle）は、「クラスはたった1つの理由でのみ変更されるべきである」という考え方です。本記事では、オブジェクト指向プログラミング（OOP）と関数型プログラミング（FP）におけるSRPの捉え方と実装方法を比較します。

#### 単一責任の原則についての詳しくはこちらで

https://shuji-bonji.github.io/Notes-on-SOLID-Principle/single-responsibility-principle.html

## OOPにおけるSRPの実装例

```ts
// OOPの例：クラスごとに責務を分離する
class ReportGenerator {
  generate(data: any): string {
    return `Report: ${JSON.stringify(data)}`;
  }
}

class ReportPrinter {
  print(report: string): void {
    console.log(report);
  }
}

// 使用例
const data = { id: 1, content: '内容' };
const generator = new ReportGenerator();
const printer = new ReportPrinter();
const report = generator.generate(data);
printer.print(report);
```
このように、生成と出力という異なる責務を別クラスに分けることで、クラス単位での責任の明確化を図ります。

## FPにおけるSRPの実装例

```ts
// FPの例：関数ごとに責務を分離する
const generateReport = (data: any): string => `Report: ${JSON.stringify(data)}`;
const printReport = (report: string): void => console.log(report);

// 使用例
const data = { id: 1, content: '内容' };
const report = generateReport(data);
printReport(report);
```

関数型では、副作用を分離することで「関数ごとの責任の明確化」がSRPの応用となります。
また、関数を合成して処理フローを作ることが容易です。

## SRPにおける比較まとめ

|観点|OOP|FP|
|---|---|---|
|単位|クラス|関数|
|責務の分離|クラスを分ける|関数を分ける・副作用を分離する|
|拡張性|サブクラス化や委譲|関数の合成や高階関数で拡張|
|テストのしやすさ|テスト用モックや依存注入|関数単位でテストしやすい|
|注意点|クラスの肥大化|状態共有がない代わりにパイプライン管理が必要|

次回は[「開放/閉鎖原則（OCP）におけるOOPとFPの比較」](https://qiita.com/bonji/items/b8ba95e4af8e5dbb70d2)について掘り下げていきます。
Google Colab で一括 OCR — YomiToku テンプレートコード

コード

````markdown
# Google Colab で一括 OCR — YomiToku テンプレートコード

> **この記事のゴール**  
> - PDF をブラウザにドラッグ＆ドロップ  
> - YomiToku が **HTML + CSV** を自動生成  
> - すべて ZIP にまとめて **ワンクリック DL**

---

## 1. Colab ノートブックを準備

1. [Google Colab](https://colab.research.google.com/) を開く  
2. メニュー **Runtime → Change runtime type** で **GPU** を選択（なくても動きます）  
3. 新しいノートブックを作成

---

## 2. コード全文（コピペ OK）

```python
# =========================
# ① ライブラリをインストール
# =========================
!pip install -q yomitoku           # 日本語特化OCR
!apt-get -yqq install poppler-utils # PDF ⇄ 画像変換

# =========================
# ② PDF をアップロード
# =========================
from google.colab import files
uploaded = files.upload()          # 画面でファイルを選ぶだけ

# =========================
# ③ YomiToku で一括 OCR
# =========================
import os, subprocess, shlex, zipfile, pathlib, uuid
from tqdm.auto import tqdm         # 進捗バー表示用

out_root = f"ocr_results_{uuid.uuid4().hex[:8]}"
os.makedirs(out_root, exist_ok=True)

for fn in tqdm(uploaded.keys(), desc="OCRing"):
    in_path = f"/content/{fn}"
    if not in_path.lower().endswith(".pdf"):
        print(f"⚠️  Skipping non-PDF: {fn}")
        continue

    safe = pathlib.Path(fn).stem
    outdir = os.path.join(out_root, safe)
    os.makedirs(outdir, exist_ok=True)

    for fmt in ("html", "csv"):    # 読む用＆加工用
        cmd = (
            f'yomitoku {shlex.quote(in_path)} '
            f'-f {fmt} -o {shlex.quote(outdir)} '
            f'-v --figure --encoding utf-8-sig --combine'
        )
        subprocess.run(cmd, shell=True, check=True)

# =========================
# ④ ZIP に固めてダウンロード
# =========================
zip_name = f"{out_root}.zip"
with zipfile.ZipFile(zip_name, "w", zipfile.ZIP_DEFLATED) as zf:
    for root, _, files_in_dir in os.walk(out_root):
        for file in files_in_dir:
            zf.write(os.path.join(root, file))

print(f"📦  OCR 結果を {zip_name} にまとめました")
files.download(zip_name)
````

***

## 3. コードのポイント

| ここが便利 | 説明 |
|------------|------|
| **ファイル名を毎回書かなくていい** | `files.upload()` で選んだ PDF を自動でループ処理 |
| **HTML + CSV を同時生成** | 読みやすい表示用と、Excel で開ける表データを一括取得 |
| **進捗バー付き** | `tqdm` がページ数の多い PDF でも残り時間を見せてくれる |
| **ZIP 一発ダウンロード** | 出力フォルダを丸ごと圧縮 → ワンクリックで PC に保存 |
| **毎回ユニークな出力フォルダ** | `uuid` で衝突防止。過去の結果を間違って上書きしない |

***

## 4. よくある質問

<details>
<summary>手書き文字も読めますか？</summary>
YomiToku は活字向けに最適化されていますが、整った手書きなら一定の精度で認識できます。崩れた筆跡やクセ字は誤読が出やすいので、まずは試して確認しましょう。
</details>

<details>
<summary>料金は？ 商用利用は？</summary>
個人・非商用なら無料。ビジネス利用は開発元へライセンス申請が必要です。
</details>

<details>
<summary>処理が遅い／落ちる</summary>
- まず Colab を **GPU ランタイム** に  
- 高解像度 PDF はページ数を分割してアップロード  
- 可視化不要なら `-v` を外すとメモリ節約
</details>

***

## 5. 使い道アイデア

*   ◎ 雑誌や小説の **縦書き OCR**
*   ◎ バス・電車の **時刻表 → CSV**
*   ◎ **野球のスコアブック** をデータベース化
*   ◎ 会議資料を **HTML 化して全文検索**

***

> **まとめ**\
> YomiToku は「日本語にめっぽう強い」OCR。\
> Colab テンプレを使えば、**アップロード → 待つ → ダウンロード** の 3 ステップで完了です。\
> ぜひ手元の PDF で試して、日本語 OCR の精度を体感してみてください！

```

---
PRML　演習問題　解答集　第10章

## はじめに
様々な分野で多様なビッグデータが得られるようになり、こうしたデータを解析し、そこから「知」を得るための手段として、**機械学習 (Machine Learning)**、いわゆる**AI**が注目されています。そういった動きは、**農学**の分野でも広がってきており、我々**[生物測定学研究室](https://www.ut-biomet.org/)**でも、圃場のモニタリングに画像解析技術を用いたり、育種（品種改良）に機械学習のアイディアを応用した研究を行ったりしています。

こうした状況を鑑みて、本研究室では2020年前期（4月〜8月）に、機械学習の教科書の決定版ともいえる、**Christopher Bishop**による**『Pattern Recognition and Machine Learning （パターン認識と機械学習）』**、通称**PRML**に関する輪読会を開講しました。本輪読会では、PRMLの各章の末尾に付いている**演習問題**を、輪読会参加者の有志が解く、ということも行いました。ここでは、各人による演習問題の解答例を`Qiita`の記事として紹介していこうと思います。
（追記：**2021年度後期**、**2024年度~**2025年度後**も輪読会を開催し、第1章から勉強しています。昨年度できなかった演習問題は随時更新予定です。）

本記事では、**第10章の演習問題の解答例**に関する記事のリンクを紹介していきます。
まだ解いた全ての問題を公開しているわけではなく、随時更新していきます。**更新内容などについては、[`Twitter`](https://twitter.com/BiometUt)にてご報告**する予定です。

（注：解答例は、数学の決して得意ではない学生によるものもあります。中には間違いや不十分な解答もあるかもしれませんが、温かい目で見ていただき、コメントで誤りなどを指摘していただければ幸いです。また、**全ての問題に対して解答例が用意されているわけではない**ので、その点についてもご了承ください。）


## 関連記事など
#### 別の章に関するリンク集　
- [PRML　演習問題　解答集　まとめ](https://qiita.com/Lab_of_Biomet/items/15e38ca34fafa8176d89)
- PRML　演習問題　解答集　第9章 ←2021年11月現在、更新予定はございません…
- PRML　演習問題　解答集　第11章 ←2021年11月現在、更新予定はございません…

#### PRML 公式資料
- [PRML 一式 ダウンロードページ （公式）](https://www.microsoft.com/en-us/research/people/cmbishop/prml-book/)
- [PRML 英語版 フルPDF （公式・無料）](https://www.microsoft.com/en-us/research/uploads/prod/2006/01/Bishop-Pattern-Recognition-and-Machine-Learning-2006.pdf)
- [PRML 日本語訳 上巻 （Amazon）](https://www.amazon.co.jp/%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3%E8%AA%8D%E8%AD%98%E3%81%A8%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92-%E4%B8%8A-C-M-%E3%83%93%E3%82%B7%E3%83%A7%E3%83%83%E3%83%97/dp/4621061224)
- [PRML 日本語訳 下巻 （Amazon）](https://www.amazon.co.jp/%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3%E8%AA%8D%E8%AD%98%E3%81%A8%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92-%E4%B8%8B-%E3%83%99%E3%82%A4%E3%82%BA%E7%90%86%E8%AB%96%E3%81%AB%E3%82%88%E3%82%8B%E7%B5%B1%E8%A8%88%E7%9A%84%E4%BA%88%E6%B8%AC-C-M-%E3%83%93%E3%82%B7%E3%83%A7%E3%83%83%E3%83%97/dp/4621061240)
- [PRML 英語版 公式解答例 （wwwの付いた一部の問題）](https://www.microsoft.com/en-us/research/wp-content/uploads/2016/05/prml-web-sol-2009-09-08.pdf)

#### PRML 非公式資料
- [PRML演習問題解答を全力で分かりやすく解説！](https://tips-memo.com/prml): この方は`PRML`の演習問題の数多く（ほとんど）の問題を、第1章から第10章まで手書きで公開しています。
- [PRML演習解答 [ゆっくり PRML していってね]](http://sioramen.sub.jp/prml_wiki/doku.php/top): この方は`PRML`の演習問題の数多く（ほとんど）の問題を、第5章から第14章まで、手書き、および一部清書した形で公開しています。
- [その他PRMLのタグがついたQiitaの記事一覧](https://qiita.com/tags/prml)

他にも、一部の記事でPRMLの演習問題の解答例に関する記事があるものの、どれも1問単位で解かれており、このようなLaTeXで数式を書いた解答例のリンク集は存在しないように見受けられます。


## 担当者
[東京大学 生物測定学研究室](https://www.ut-biomet.org/)の @YusukeToda1984 さん, @ZaKama さん, @patten さん, @Kazutoshi08 さん, @mashiro135 さん, @KimuraSoh さんにご協力いただきました。また、他にも（生物測定学研究室以外の学生を含む）2名の有志が匿名で公開に協力してくださいました。こちらの2名の方の記事はこのアカウントの記事として投稿させていただいもののリンクを紹介したいと思います（当人の許可をとっています）。さらに第5章からは、@yoyoyo11131113 さんにもご協力いただけることになりました。


## 解答　リンク集
##### 図の実装
- [図の実装](https://qiita.com/KimuraSoh/items/7ea24d067ecdc437a59b) （@KimuraSoh さん）
##### 演習問題 10.3 （標準）
- [PRML 演習問題10.3(標準) 解答](https://qiita.com/yutafukumotogo/items/44916c169e834da8548f) (@yutafukumotogo さん)
##### 演習問題 10.6 （標準）
- [PRML 演習問題10.6(標準) 解答](https://qiita.com/KimuraSoh/items/dbd1bb7353e1d2f056fa) （@KimuraSoh さん）
Qiita1年目の成果報告：13記事投稿で表示回数2.6万突破！伸びた記事に共通する2つのポイント

# はじめに
こんにちは、Zukki2です。
閲覧ありがとうございます。大変励みになっています。

Qiitaを始めて約1年が経ちました。本記事では、半年前に投稿した以下の記事と同じようにこれまでの振り返りをします。

https://qiita.com/zukki2/items/5e29d46b5b06a50d7ac9

私と同じようにQiitaに記事を投稿している方・これから投稿しようと考えている方の参考になれば嬉しいです。

# 主要指標の推移（左：2024/4~2024/10、右：2024/4~2025/4）
投稿：8→13
Contributions：64→162
いいね：30→92
ストック：51→111
views：1.4万→2.6万（※今回からはGoogle Analyticsの「表示回数」を使用のため、Qiitaのviewより少なめに表示されている）

※スクショを貼り忘れたため、投稿後追記しました。そのため本記事の分投稿数とcontributionsが1ずつ増えてます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3770170/d5732b7f-4450-4ba2-8b06-3005c9c17796.png)


# 今回
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3770170/b94ae83c-0580-48e5-8b9d-907ae657ffa6.png)

Google Analyticsのグラフを見ると線形的に表示回数が増えていることがわかります。

# 前回
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3770170/a3e8eb93-ff01-4f2c-8b5d-162828651934.png)

前回の結果と比べても表示回数などが着実と伸びていることがわかります。

# 記事別の推移
ここで注目いただきたいのは記事別の表示回数の推移です。
私の書いた記事の中で閲覧数の多いtop3を表示しました。緑と紫の折れ線グラフは横ばいのため、定期的に読んでくださる方がいることがわかります。
一方で、青い実線は10月に記事を投稿して以来、毎月右肩上がりで読者が増えています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3770170/9754256d-eecc-4b79-8aa1-9f8bc70861b2.png)

青い線の記事は以下のようにgemini apiのチュートリアル記事です。
キャッチーなタイトルとgeminiに対しての注目度の上昇から、表示回数が増えていると考えられます。

https://qiita.com/zukki2/items/10bfeb1c4330aa18ff87

ここまでの結果を振り返ると表示回数を増加させたい時に注目できるポイントが2点あることに気づきます。

1つは、トレンドに乗ることの重要性です。上述のように、右肩上がりに注目度が増すような領域の記事を書くことが表示回数アップの近道だと考えられます。

2点目は、沢山アウトプットすることの重要性です。私はかなりニッチな記事も書いていますが、そのような記事でも定期的に読みにきてくれる人がいます（むしろそういった記事のほうが役に立っていると信じています）。一度投稿した記事は、ずっと残り続けます。急に検索結果に表示されなくなるようなこともありません。だからこそ地道に誰かのプラスになるための記事を書き続けることが一番重要なのだと実感しています。

# まとめ
Qiitaは、自身のアウトプットの場であり、ナレッジシェアの場でもあります。
その目的を考えると、必ずしも表示回数やリアクション数を追い求める必要はないかもしれません。

しかし、「モチベーションの維持」や「良質なナレッジ共有の促進」といった観点では、表示回数やいいね数などの指標は、個人にとってもコミュニティにとっても価値のあるものだと感じています。

これからも試行錯誤しながら、地道に記事を書き続けていきたいと思います。

### P.S.
今回は実験的に、タイトルをChatGPT-4oに書いてもらいました（本文は全て自分で書いてます）。
違和感があればぜひコメントで教えてください。
AWS Graviton対応

# Gravitonとは
- AWSが独自開発するプロセッサ
- amd64よりもコスパがよく省電力
- インスタンスはgがつくものを採用する
- Windowsサーバーに対応していない
- ARM対応が必要

# 移行方法
### EC2
- 現在使っているインスタンスタイプに近いgのついたものを採択

### Lambda
- 表示設定からアーキテクチャをONにしてarm64になっているか確認
- x86_64になって入れば対応必要
    - コードタブ>ランタイム設定>アーキテクチャからarm64を選ぶ
    - CDKの場合はリファレンス参照して設定

### ECS,Fargate,Batch
- コンピューティング環境から使っているインスタンスタイプを確認してgをつくものに変更

### ECR
- イメージ作成の際にamd64に依存したパッケージを使っていないか確認
    - ベースイメージは docker manifest inspect <pakegename> |grep architecture でarm64が出てきたらOK
    - Pythonだったら、import platform; print(platform.machine())でarm64ならOK
    - 他パッケージは apt-cache show <packagename>でarchitectureにallかarm64と表示されていたらOK
世界最速で rails new したい

## はじめに

新規プロダクト開発の際「とにかくrails newで雛形を作りたい、下準備とか何もやりたくない」というのは、稀に良くあると思います。

その際は以下のコマンドで一発okです
※オプションは適宜編集してください

```shell
docker run -it --rm \
  -e HOME=/rails \
  -v $(pwd):/rails \
  -w /rails \
  --entrypoint /bin/bash \
  ruby:3.4 \
    -c "gem install rails && \
        rails new screening --database=mysql \
              --skip-action-mailbox \
              --skip-action-text \
              --skip-active-storage \
              --skip-action-cable \
              --skip-hotwire \
              --skip-jbuilder \
              --skip-test \
              --skip-system-test \
              --skip-thruster \
              --skip-ci \
              --skip-kamal \
              --skip-solid \
              --skip-bundle"
```

カレントディレクトリをマウントしているので、ホストマシンに雛形ができているはずです。

複雑なことをやる場合は、一度containerに入ってからコマンドを打てばok牧場です。


```shell
docker run -it --rm \
  -e HOME=/rails \
  -v $(pwd):/rails \
  -w /rails \
  ruby:3.4 /bin/bash

gem install rails && \
rails new screening --database=mysql \
                    --skip-action-mailbox \
                    --skip-action-text \
                    --skip-active-storage \
                    --skip-action-cable \
                    --skip-hotwire \
                    --skip-jbuilder \
                    --skip-test \
                    --skip-system-test \
                    --skip-thruster \
                    --skip-ci \
                    --skip-kamal \
                    --skip-solid \
                    --skip-bundle
```

全てのエンジニアに幸あれ。
ネットワークスイッチとは

「ネットワークスイッチ（Network Switch）」とは、コンピュータネットワークにおいて**複数の機器を接続し、通信データを効率よく中継する装置**のことです。

---

### 🔹 主な役割
- **LAN内の通信を管理**：どの機器にどのデータを送るかを判断して転送。
- **MACアドレスをもとに通信先を決定**：無駄なデータ転送を減らし、ネットワークの効率を上げる。
- **ハブより賢い**：ハブは全ポートにデータを流すが、スイッチは必要なポートだけに流す。

---

### 🔸 簡単な例
オフィスのPCやプリンタなどをネットワークでつなぐときに、スイッチを使ってまとめて接続し、データを必要な機器に届けてくれます。

---


レイヤー2スイッチとレイヤー3スイッチの違い

---

### ✅ レイヤー2スイッチ（L2スイッチ）

- **動作レイヤー**：OSI参照モデルの**第2層（データリンク層）**
- **判断基準**：**MACアドレス**
- **主な用途**：同じネットワーク（同一セグメント）内の機器同士をつなぐ
- **役割**：データを正しい機器に中継（LANスイッチ）

📌 **イメージ**：  
「同じ部屋の中で、誰に話しかけるかを顔（MACアドレス）で判断して声をかける」

---

### ✅ レイヤー3スイッチ（L3スイッチ）

- **動作レイヤー**：**第3層（ネットワーク層）**
- **判断基準**：**IPアドレス**
- **主な用途**：異なるネットワーク（別セグメント）間の通信も処理可能
- **役割**：**ルーティング（簡易ルーター機能）**ができるスイッチ

📌 **イメージ**：  
「別の部屋（ネットワーク）にいる相手にも、部屋番号（IPアドレス）を見てメッセージを届けに行く」

---

### 🔄 ざっくり比較表

| 項目 | レイヤー2スイッチ | レイヤー3スイッチ |
|------|------------------|------------------|
| 処理基準 | MACアドレス | IPアドレス |
| 役割 | 機器同士の接続 | ネットワーク間の接続 |
| ルーティング機能 | なし | あり |
| 使用場面 | LAN内通信 | VLAN間通信なども含む |

---
RubyKaigi2025に参加しました

初めてRubyKaigiに参加してきましたので、印象に残ったセッションについて簡単にまとめます。

## Make Parsers Compatible Using Automata Learning
https://rubykaigi.org/2025/presentations/makenowjust.html#day1

オートマトン学習を使ってRubyのパーサーの違いを発見した発表でした。parse.yとPrismという2つの異なるパーサーから学習したオートマトンを比較することで、両者の動作の違いを効率的に見つけられるというアプローチが紹介されていました。

## Continuation is to be continued
https://rubykaigi.org/2025/presentations/fetburner.html#day1

Rubyの継続オペレータであるcall/ccとその課題を解決するshift/resetについての解説でした。継続オペレータはプログラムの実行位置を記録し、後で任意のタイミングでその位置に戻るための機能です。

## Goodbye fat gem 2025
https://rubykaigi.org/2025/presentations/ktou.html#day1

Fat gem（ビルド済みのバイナリを含むgemパッケージ）のメンテナンスの難しさについての発表でした。Rubyのバージョンアップや脆弱性対応のたびに、複数の環境向けにビルドし直す必要があり、メンテナンスがとても大変そうでした。

## Ruby's Line Breaks
https://rubykaigi.org/2025/presentations/spikeolaf.html#day1

Rubyの文法ファイルの分析を通じて、どのような条件で行区切りが無視されるか、あるいは有効になるかについての技術的な解説でした。オートマトンを応用した分析方法も紹介され、面白かったですが難しかったです。

## dRuby on Browser Again!
https://rubykaigi.org/2025/presentations/youchan.html#day1

dRubyとruby.wasmを組み合わせたブラウザ上でのRuby実行についてのセッションでした。wandsというライブラリを使ったデモも行われ、WebブラウザでRubyを活用する可能性が示されていました。

## Official Party
様々な参加者と交流でき、楽しかったです。Rubyコミュニティの温かさを実感できる機会となりました。

## Dissecting and Reconstructing Ruby Syntactic Structures
https://rubykaigi.org/2025/presentations/ydah_.html#day2

Rubyの柔軟な構文がパーサーの複雑さと表裏一体であるという視点からの発表でした。言語の使いやすさを実現するために、裏側では複雑な処理が行われていることが分かりました。

## Making TCPSocket.new "Happy"!
https://rubykaigi.org/2025/presentations/coe401_.html#day2

Happy Eyeballs（IPv4/IPv6デュアルスタック環境での接続最適化技術）をTCPSocket.newに実装した事例についての発表でした。実装の詳細や直面した課題の説明は技術的に難しかったですが、開発過程の苦労を聞き、とても勇気づけられました。

## Analyzing Ruby Code in IRB
https://rubykaigi.org/2025/presentations/tompng.html#day3

irbの自動補完やシンタックスハイライト機能の実装詳細についての発表でした。一見シンプルに見える機能の裏側には、多くの考慮点や工夫があることが分かりました。

## 感想
初めてのRubyKaigiで初めて聞く単語も多くセッションの内容はあまりわからなかったですが、Rubyって面白いなーという気持ちになれて良かったです。また参加したいと思います。
プロセスとOSユーザーの違いとは？

## はじめに
「プロセスは実行中のプログラムのこと」とは理解していたものの、
「OSユーザーってそもそも何者なのか？」
「www-data や mysql って、プログラムじゃないの？」
といったところで混乱したので、自分の中で整理した内容をまとめておく。

## プロセスとOSユーザーは別物

例えば、python3 script.py を実行すれば python3 というプロセスが起動する。
そのプロセスは「誰が実行したのか？」という情報（＝OSユーザー）を持っている。

## OSユーザーとは？
OSユーザーとは、OS内に登録された“名前付きの利用者”であり、
プロセスを実行する“主体”を示すもの。

ubuntu：普段使う人間用ユーザー（ログイン用）

www-data：Webサーバー専用のユーザー（Apache/Nginxなどがこの名義で動く）

mysql：MySQL専用ユーザー（mysqldがこの名義で動く）

root：管理者ユーザー（すべての権限を持つ）

これらはプロセスではないし、実行ファイルでもない。
ただの名義。そのプロセスがどのユーザーの責任で動いているかを表す。


## なぜOSユーザーを分けるのか？
結論「全部をrootで動かすと何でもできてしまって危険」だから。

Webサーバーが乗っ取られても、www-dataユーザーなら他の重要ファイルにはアクセスできない。

mysqldはmysqlユーザーで動いていれば、データベースの領域だけ触れる。

それぞれのプロセスに必要最小限の権限だけを与えることで、セキュリティが保たれる。

## まとめ
プロセス：実際に動いているプログラム

OSユーザー：そのプロセスを動かしている“名義”

OSユーザー自体はプログラムではないし、実行されているものでもない

プロセスには必ず「どのOSユーザーが動かしているか」という情報がある

OSユーザーを分けることで、安全にプロセスを管理・実行できる

自分としては、「プロセスは実行されているプログラム」「OSユーザーはそのプロセスの名義」と整理することで
ようやく腑に落ちた。

同じところでつまずいた人の参考になれば。
【初心者向け】matplotlibを使ったデータ可視化

# はじめに
今回はmatplotlibを使ったデータ可視化についての備忘録を兼ねた記事です。
matplotlibは、Pythonのライブラリで折れ線グラフや棒グラフ等を作成してくれます。

今回使用するライブラリは下記になります。
	•	pandas
	•	matplotlib
	•	seaborn（おまけ）

インストールしてない方は以下でインストールできます。半角スペースを入れると一括でインストールしてくれます。
```
pip install pandas matplotlib seaborn
```
# CSVを読み込む

今回はサンプルとして、以下のような「仮想の売上データ」を使っていきます（実際には自作DataFrameにするので、CSV不要です）。
```python
import pandas as pd

# サンプルデータを作成
data = {
    '日付': ['2025-04-01', '2025-04-02', '2025-04-03', '2025-04-04', '2025-04-05'],
    '売上': [10000, 12000, 8000, 15000, 13000],
    '商品数': [20, 25, 15, 30, 28]
}

df = pd.DataFrame(data)
print(df)
```
# 折れ線グラフで可視化
```python
import matplotlib.pyplot as plt

plt.plot(df['日付'], df['売上'])
plt.title('売上推移')
plt.xlabel('日付')
plt.ylabel('売上（円）')
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()
```
ポイント：
	•	plt.plot() で線グラフを描く
	•	xticks(rotation=45) で日付を見やすくする
	•	tight_layout() でレイアウトを自動調整する
# 棒グラフで商品数を比較してみる
```python
plt.bar(df['日付'], df['商品数'])
plt.title('日別商品販売数')
plt.xlabel('日付')
plt.ylabel('商品数')
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()
```
棒グラフは「数量比較」に向いています。
# おまけ
seabornを使用するとでおしゃれなグラフにすることも可能です。
```python
import seaborn as sns

sns.set(style='whitegrid')  # スタイルを設定

sns.lineplot(x='日付', y='売上', data=df, marker='o')
plt.title('【seaborn】売上推移')
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()
```
Seabornはスタイルが良くて、色も自動で綺麗ですね。
使い方はmatplotlibと似ているので、すぐに慣れると思います。

⸻

まとめ

以上がmatplotlibの基本的な使い方になります。
他にもヒストグラムや散布図など様々なグラフを描画しデータを可視化してくれます。
可視化は、データ分析の最初のステップとしてとても大事です。「数字だけじゃよくわからない」を、「パッと見てわかる」に変えてくれる力があります。
補数を噛み砕く　Part1

コンピューターは引き算が出来ない。だから補数という概念を使って、足し算で引き算を完結させる。補数を足して桁を除けば引き算になる意味が分からなかった。なので、こちらで噛み砕きます。超初心者の噛み砕き場所なので、間違ってたらゴメンね。
5-3=2　3の補数10-3=7 5+7=12→2
これは5-(10-7)=5-10+7=5+7-10
だから補数を足して追加された桁を除けば大丈夫！
2進数でも同じ。0011-0001の場合、0011-(10000-1111)=0011+1111-10000=10010-10000=0010になる、
補数表現による1111 1111は-1。これは0000 0001の補数に該当するから。1111 1111に0000 0001を足すと1 0000 0000となり、結果ゼロになる。足してゼロになるという事はマイナス1に該当する、
ITにおける全体最適化の難しさ

思い付きメモです。(訴訟やら含めてもっとひどい話にしようと思ったけど、長くなりそうなのでひとまずこれで)
マサカリ歓迎。


あるところに10店舗のお店を持った会社がありました。
その会社はシステム化にいち早く取り組み、手作業で行うなら100人必要な作業が10人でできるようになっていました。
ある日、その会社の偉い人が言いました

「全店舗で同じシステムを使うようにして全体最適化を行う。これでシステムにかかる費用が削減できるはずだ」

しかし、そう簡単にうまくいきません。
要件定義を進めていると個別最適化で業務を削減で来ていたところがうまくできなくなり、今まで10人でできていたことが20人必要になることが分かったのです。

「それなら各店舗用にアドオン開発をしよう」

結果、データ連携とかERP的な部分はちょっとましになったものの、システム費用に掛かる費用は対して変わりませんでした。

おしまい