OmniAICreator/Qiita-1.07M huggingface dataset:
【複数項目の並べ替えにも使える！】LookerStudioでよく使うCONCAT関数

みなさん、こんにちは！

突然ですが、LookerStudioには関数がたくさんあります。
大きく分けると、集計、算術、条件付き、日付、地域、テキスト、その他の7種類に分けることができます。

その中でも、私が業務でよく使用しているのがCONCAT関数です。
通常、このCONCAT関数は項目の結合に使用されていることが多いですが、表内の複数の項目の並び替えを行いたいときにも使用できたので紹介したいと思います。

## CONCAT関数とは？
最初にCONCAT関数に関してとても簡単に説明します。
CONCAT関数とは2つ以上の文字列を結合することができる関数です（構文：CONCAT(X, Y [,Z, ...])）。

もう少し詳しく関数について知りたい方はこちらをご覧ください！
[https://support.google.com/looker-studio/answer/7583443?hl=ja](https://support.google.com/looker-studio/answer/7583443?hl=ja)

## 普段の使用方法
最初にご説明したように、このCONCAT関数は普段項目の結合に使用されることが多いです。
項目の結合というのは、別々になっている項目をまとめるイメージです。
通常、LookerStudioの表に項目を追加すると、表のように【氏名】【氏名(ひらがな)】【氏名(カタカナ)】のように項目が分かれてしまいます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3956386/d3fc2ec6-7ce5-4576-aab9-8086d9027048.png)

このそれぞれの項目を一つの項目として扱いたい場合があるかもしれません。

そのような時に利用するのが**CONCAT関数**です。
方法としてはとても簡単で、「ディメンション(または指標)を追加」をクリック→「計算フィールドを追加」から関数を入れるだけです！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3956386/2a33b360-7904-4b93-b676-479e882794c9.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3956386/e0b00140-9b97-4dc8-8eab-25df9fc05327.png)

今回は【氏名】【氏名(ひらがな)】【氏名(カタカナ)】を結合した【顧客】という項目を実際に右側に新しく作成してみたいと思います！
まず先程記載したように「ディメンション(または指標)を追加」をクリック→「計算フィールドを追加」をクリックします。
計算フィールドの設定画面で下記を入力し、適用をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3956386/fed24c56-c71d-41e7-9897-b12ed28de3fd.png)

名前：顧客
データの種類：テキスト
計算式：CONCAT(【氏名】,"：",【氏名（ひらがな）】,"：",【氏名（カタカナ）】)

適用を押すと【氏名(カタカナ)】の列の右側に【氏名】【氏名(ひらがな)】【氏名(カタカナ)】を合わせた【顧客】という項目を追加することができました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3956386/207b5493-c87b-4526-8706-320a67ac56fa.png)

## 3項目以上の並び替え
上記で紹介したように、通常は複数の項目を一つにまとめることなどに使用されているCONCAT関数ですが、複数項目の並び替えの際にも使用することができます！

LookerStudioでは設定の「並び替え」から並び替えを行いたい項目を選択することで、表示する順番を変更できます。
しかし、この機能を使うと「並び替え＋サブ」の２つの項目しか設定することができません。
今回、【年齢】【性別】【血液型】で並び替えを行いたいとします。
項目は2つまで設定できるので【年齢】【性別】は並び替えることができますが、血液型がバラバラになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3956386/3f1f0066-7bd3-480c-b625-54b30852bb57.png)

このように3項目以上で並び替えを行いたい時に、CONCAT関数を使うことで実現することができます！
実際に行ってみました！

今回、【年齢】【性別】以外に【血液型】を含めた3項目の並び替えを行います。
方法は、先程ディメンション(または指標)で項目を結合する方法とほぼ一緒で、「並び替え」をクリック→「計算フィールドを追加」から設定することで3項目以上の並び替えを行うことができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3956386/94afb76d-d5d6-48e0-b2fb-5bddc96cf566.png)

普通に設定を行うと、
「24歳の女性→24歳の男性」
までしか並び替えを行えませんでしたが、CONCAT関数を使用することで
「24歳女性B型→24歳女性O型→24歳男性B型→24歳男性O型」
というように血液型まで含めた並び替えを行うことができました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3956386/6ff62f58-9d40-411b-ab68-fdbe5bcf32d9.png)

## まとめ
今回は、LookerStudioでよく使用される関数CONCAT関数の意外な使い方に関してご説明させていただきました！
LookerStudioは無料のサービスのため、できることが制限されていることもありますが指標やフィールドに関数を使用することによってできる幅を増やすことができます。
今後もLookerStudioを始めとしたBIツールのTipsについても投稿していこうと思いますのでご期待ください！
「カチャカ」ロボット開発の最前線！徹底的に思い込みを捨て、ユーザーの声を聴く

こんにちは。先日、Qiitaの記事で、「<a href="https://qiita.com/GIFCat/items/ed83b74b89e2454167de">爆速でアプリ開発！ 他社に負けないスピード開発の秘訣</a>」をご紹介しました🌈

続いて本記事では、次世代型ハッカソンの一環として2024年3月に開催された「<a href="https://www.youtube.com/playlist?list=PL8rtY-KIcZTdqRNTZJsP74PG4Ctptfy76/">GIFTech Academy</a>」での、Preferred Roboticsの「kachaka（カチャカ）」開発責任者である寺田耕志氏のセッションをご紹介😺

次世代の家庭用自律移動ロボット「kachaka」が、「第11回 ロボット大賞」にて「総務大臣賞」を受賞するなど、ロボット技術の発展や活用が各方面から評価を受けているカチャカさん。

機能的に優れているだけでなく、実際に「売れる」「家庭で使われる」プロダクトを作るには・・？真摯に向き合いつくした同社の実例を語っていただきました。

↓ 「kachaka」についてはこちらから

https://kachaka.life/

https://prtimes.jp/main/html/rd/p/000000029.000115855.html

講義の中から、**生活に溶け込むロボット開発5つのポイント** としてご紹介します💪💪💪

↓　講義動画はこちらからご覧いただけます。
<iframe width="560" height="315" src="https://www.youtube.com/embed/DB_lhaJIkBM?si=oCN1unBUJOQo0LYX" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>


## 1. ユーザー視点の徹底

ロボット開発では、**開発者の先入観を排除し、実際のユーザーのフィードバックを重視することが重要**です。特に、一般家庭でのテストを通じてリアルなニーズを把握することが、実用的な製品づくりにつながります。例えば、見た目の未来感よりも「どのように生活を便利にするか」という視点が求められます。

:::note info
・先入観を排除し、実際のユーザーのフィードバックを重視。
・一般家庭でのテストを通じて、リアルなニーズを反映した製品開発を進める。
:::

## 2. 機能のシンプル化と実用性重視

ロボットに多機能を詰め込むのではなく、**シンプルで実用的な機能に特化することが大切**です。「物を運ぶ」などの基本機能にフォーカスし、ユーザーが直感的に使えるデザインを優先することで、日常に溶け込みやすくなります。高度な技術を誇示するのではなく、**生活者目線での利便性を最優先に考えるべき**です。

:::note info
・「物を運ぶ」機能に特化し、使いやすさを優先。
・高度な技術よりも、生活に溶け込むシンプルな操作性を重視。
:::

## 3. ハードウェア開発の特有の難しさ

ソフトウェアとは異なり、**ハードウェアは一度製造するとアップデートや修正が容易ではありません**。開発コストや生産期間の制約もあり、慎重な設計と徹底したテストが不可欠です。たとえば、耐久性や安全性の確保は、家庭用ロボットが普及するうえで避けて通れない課題となります。

:::note info
・ソフトウェアと違い、ハードウェアはアップデートや修正が容易ではない。
・コストや開発期間の制約が厳しく、慎重な設計とテストが必須。
:::

## 4. マーケティングと開発の融合

技術開発だけではなく、マーケティング戦略を並行して進めることも成功の鍵です。ターゲット層を明確にし、どのように認知を広げていくかをエンジニアとマーケターが協力して検討する必要があります。たとえば、**家庭向けロボットならば、家事負担の軽減を訴求するなど、技術にフォーカスしないプロモーションが大切**です。

:::note info
・技術開発だけでなく、マーケティング戦略を並行して進める。
・ターゲット層の選定や認知戦略を、エンジニアとマーケターが協力して検討。
:::

## 5. ロボットを新しい家電として普及させる

カチャカでは、ロボットを特別な存在ではなく、冷蔵庫や掃除機のような **「生活を支える家電」として普及させることを目標**としています。そのためには、価格やデザイン、操作性を家庭向けに最適化することが不可欠です。日本の技術力を活かし、国内市場だけでなく世界市場での展開も視野に入れた戦略を立てることで、より多くの家庭にロボットが受け入れられるでしょう。

:::note info
・生活を支える家電としてのロボットを目指し、実用的な市場投入を図る。
・日本の技術力を活かし、世界市場での展開も視野に入れる。
:::

## まとめ

ロボット開発の成功には、技術力だけでなく、ユーザーの本当のニーズを理解し、それを形にする力が不可欠です。kachakaの開発プロセスからは、ユーザー視点の重要性や、市場で求められるプロダクトを生み出すための工夫が学べます。

動画では、若きエンジニアに向けて「ユーザーに受け入れられるプロダクト」の作り方や、チームで開発をしていく際に重要なことなどについてもお話しいただいています！

↓　もっと詳しく知りたい方は、GIFTech Channelでご覧ください🔍

https://www.youtube.com/@GIFTechCH
ハッカソン個人備忘録⑤：FastAPI + MySQL ローカル開発環境構築（Docker Compose対応）

## はじめに
この記事では、FastAPI と MySQL を組み合わせ、Docker Compose を使って簡単にローカル開発環境を構築する方法を紹介します。

:::note info
**コピペでそのまま使えるセットアップになっており、FastAPIをこれから学びたい方や、最小構成で動く環境をすぐに用意したい方にもおすすめです。**
:::

ホットリロードやSwagger UIを活用して、効率よく開発を進めることができます。

---

## 書こうと思ったきっかけ
FastAPIの学習を進める中で、まず「動く環境」を整えるまでに意外と時間がかかりました。

:::note warn
***特にMySQLとの接続やDockerの設定でつまずくことが多く、都度ネットで調べては試す…という繰り返しでした。***
:::

同じようなところで悩む人の助けになればと思い、自分の中で整理がついたこのタイミングで記事にまとめることにしました。

---

### ディレクトリ構成

```
project/
├── app/
│   ├── main.py
│   ├── requirements.txt
├── Dockerfile
├── docker-compose.yml
└── .env
```

---

### app/main.py

```python
from fastapi import FastAPI
import mysql.connector
import os

app = FastAPI()

@app.get("/")
def read_root():
    return {"message": "Hello from FastAPI + MySQL in Docker!"}

@app.get("/db-status")
def db_status():
    try:
        connection = mysql.connector.connect(
            host="db",
            user=os.getenv("MYSQL_USER"),
            password=os.getenv("MYSQL_PASSWORD"),
            database=os.getenv("MYSQL_DATABASE")
        )
        if connection.is_connected():
            return {"db_status": "connected"}
    except Exception as e:
        return {"db_status": "error", "details": str(e)}
```

---

### app/requirements.txt

```txt
fastapi
uvicorn[standard]
mysql-connector-python
```

---

### Dockerfile

```Dockerfile
FROM python:3.11-slim

WORKDIR /app

COPY app/requirements.txt .

RUN pip install --no-cache-dir -r requirements.txt

COPY app/ .

EXPOSE 8000

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]
```

---

### docker-compose.yml

```yaml
version: '3.9'

services:
  web:
    build: .
    container_name: fastapi-app
    ports:
      - "8000:8000"
    volumes:
      - ./app:/app
    env_file:
      - .env
    depends_on:
      - db
    command: uvicorn main:app --host 0.0.0.0 --port 8000 --reload

  db:
    image: mysql:8.0
    container_name: mysql-db
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      MYSQL_USER: ${MYSQL_USER}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
    ports:
      - "3306:3306"
    volumes:
      - db-data:/var/lib/mysql

volumes:
  db-data:
```

---

### .env

```env
MYSQL_ROOT_PASSWORD=rootpassword
MYSQL_DATABASE=fastapi_db
MYSQL_USER=fastapi_user
MYSQL_PASSWORD=fastapi_pass
```

---

### 起動コマンド

```bash
docker compose up --build
```

---

### 動作確認

- アプリ確認: http://localhost:8000/
- DB接続確認: http://localhost:8000/db-status
- Swagger UI: http://localhost:8000/docs

---

### ホットリロード

- `uvicorn` の `--reload` で自動リロード
- `volumes: ./app:/app` でコード変更が即反映

---

### よくある次のステップ

- SQLAlchemy や Alembic を用いたORM開発
- GUIツール (DBeaver, MySQL Workbench) でのDBアクセス
- テーブル作成や初期データ投入

---

## まとめ
今回紹介した構成を使えば、FastAPI と MySQL を組み合わせた開発環境を手軽に構築できます。Docker Compose と `.env` を使うことで管理もしやすく、ホットリロードや接続確認なども簡単に行えます。
今後はこのベースに、SQLAlchemy やマイグレーションツールなども加えながら、より本格的な開発環境へ発展させていけたらと考えています。
RDB設計思想を理解する「多対多」と「中間テーブル」の意味を整理

WebサービスなどでDB設計をするとき、よく適当にテーブルを設計して「このテーブルにもID一覧持たせておけばよくないかな」と考えてしまいがちな人向けに、RDBでなぜ「中間テーブル」を用いるのかを「多対多」をキーワードになるべくまとめます。

---

## 情報モデル

以下のようなモデルを例にします：

- `User` : ユーザー
- `Post` : 投稿記事
- `Tag` : タグ
- `PostTag` : タグと投稿の関係を管理する中間テーブル

---

## 問題起点

「Postについているタグ名を持たせたいなら`post` テーブルに `tag_name` からなる列を持たせれば良いじゃん？」と思うことがあります。しかしこれはRDBの設計思想に反します。

---

## ユーケース: Post ID=1 の投稿に付けられたタグを取得したい

例：
```sql
SELECT t.id, t.name
FROM PostTag pt
JOIN Tag t ON pt.tag_id = t.id
WHERE pt.post_id = 1;
```

これにより、Postに繋がる複数のタグをもれなく取得できます。

---

## なぜ中間テーブルを作るの？

### 1. 多対多を表現するには、テーブルを分ける必要がある

1つのPostに複数のTag、そのTagは別のPostにも使われる。
これが「多対多 (N:N)」の構造。

RDBでは、多対多を表現するときに「中間テーブル」を作ります：

```text
Post (1) ---< PostTag >--- (1) Tag
```

---

### 2. 1つの行に複数値を持たせない (1NF)

NG例：
| post_id | tag_names              |
|---------|------------------------|
| 1       | "アウトドア,一人OK,自然" |

- 検索しづらい
- 表示ゆれが起きやすい
- 更新が難しい

---

### 3. Tagはマスタデータ

Tagは名前や色情報を含んだ「定義情報」として別て管理するのがメンテナンス性が高い。

- Tagの名前を変更するところは1ーexecuteで手忙で管理できる
- Post側のデータは変える必要がない

---

### 4. JOINすれば欲しい情報はすぐに取れる

タグ名が欲しければ、JOINするだけ。

---

## まとめ

| 項目 | 理由 |
|--------|------|
| 中間テーブルを作る | 多対多を表現するため |
| Tag名を持たせない | Tagテーブルから取れば良い |
| 同じTagを複数使い回せる | データ重複を避けるため |
| 変更性が高い | 1か手を入れるだけで全体に反映 |

---

## 後記

今回のメモは、自分でDBを設計する際に「なぜ中間テーブルを作るのか」を説明できるようにするための理解の基礎を整理したものです。
もっと難しいテーマ(グループ化や縦方スケーリング)を考える前に、この基本を理解していることが重要です。

全体のテーブル設計の流れやユーケースの定義、ER図化なども別記事で何回かに分けて書く予定です。
画面フローの例　：　画面にある検索条件でレコードをフィルターする




![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/30c4bedd-c576-4ec6-a9f3-6e512c56031d.png)

+ Get Record

ここではレコードをある条件で抽出してコレクション変数に保存している

+ Filter for Status

上記のコレクション変数のステータスを現在のステータス（これは後で画面の選択肢をセットします）と一致したレコードだけを抽出

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/cf011824-2901-47f8-aaca-00a1bd6008c6.png)

+ Assign filter

次の画面のデータテーブルで使うコレクション変数に抽出結果を格納する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/7675f8a1-a97d-4df2-b76a-2600f61d3812.png)


+ 画面

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/976765ab-400a-40ce-91da-28bab1c1d00d.png)


+ Update Filter

現在のフィルターを画面から選択した値に置き換えます
この後Filter for Statusに行って、画面で止まります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/b32af80e-31b8-45c2-84d7-5a103dacbe6e.png)

+ 実際の動き

起動してすぐは、現在のフィルターに値はないので、一致するものがなく何も表示されません。
デフォルトをセットしてもいいかもしれませんね

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/30f10ba0-ccc7-499f-8939-a083868f0709.png)

画面からフィルターを選ぶと


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/8a2c5120-6765-40f7-aa39-08fb4915d417.png)

選んだ選択肢を保持しないですね。

デフォルト値にカレントフィルターをセットします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/66c4235a-71fb-43a6-8cf1-b8bc61f3c24d.png)

ちゃんと選択した値を保持できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/a4312968-05c3-445e-a22c-db14744b2a33.png)
Mac Studio M3 Ultraでmlx-lmを使ってllama4 Scoutを動かす

# 背景・目的

- [llama4](https://ai.meta.com/blog/llama-4-multimodal-intelligence/)がリリースされた
- Llama4 Scount は1000万トークンのコンテキスト長を持つということなので、試してみた

# コード

以下のように4-bit量子化版を使ってmlx-lmを使って推論させてみた。mlx-lm==0.22.4なら以下でOK。
0.22.3なら、[こちらのPR](https://github.com/ml-explore/mlx-lm/pull/74/files)からllama4.pyを使っているpythonの`site-packages/mlx_lm/models/llama4.py`に配置する

```python
from mlx_lm import load, generate

model, tokenizer = load("mlx-community/meta-llama-Llama-4-Scout-17B-16E-4bit")


prompt = """
以下のコードで、stopトークンを設定する方法を教えて

<code>
from mlx_lm import load, generate

model, tokenizer = load("mlx-community/meta-llama-Llama-4-Scout-17B-16E-4bit")


prompt = ""

if tokenizer.chat_template is not None:
    messages = [
        {"role": "system", "content": "あなたは優秀なソフトウェアエンジニアです"},
        {"role": "user", "content": prompt},
    ]
    prompt = tokenizer.apply_chat_template(
        messages, add_generation_prompt=True
    )

generate(model, tokenizer, prompt=prompt, verbose=True)
"""

if tokenizer.chat_template is not None:
    messages = [
        {"role": "system", "content": "あなたは優秀なソフトウェアエンジニアです"},
        {"role": "user", "content": prompt},
    ]
    prompt = tokenizer.apply_chat_template(
        messages, add_generation_prompt=True
    )

generate(model, tokenizer, prompt=prompt, verbose=True)
```

# 結果

ピークメモリ60GBで、45トークン/秒の速度で生成。
生成されたコードは、存在しないパラメータを出力していたため、ハルシネーションは発生していた

```
==========
stopトークンを設定するには、generate関数のstop_tokensパラメータを使用します。stop_tokensは、生成を停止するトークンのリストです。

例えば、以下のようにstopトークンを設定できます。

<code>
from mlx_lm import load, generate

model, tokenizer = load("mlx-community/meta-llama-Llama-4-Scout-17B-16E-6bit")


prompt = ""

if tokenizer.chat_template is not None:
    messages = [
        {"role": "system", "content": "あなたは優秀なソフトウェアエンジニアです"},
        {"role": "user", "content": prompt},
    ]
    prompt = tokenizer.apply_chat_template(
        messages, add_generation_prompt=True
    )

stop_tokens = ["
"]

generate(model, tokenizer, prompt=prompt, verbose=True, stop_tokens=stop_tokens)
</code>

この例では、stop_tokensに["
"]を設定しています。これにより、生成が"
"トークンに達すると停止します。

stop_tokensパラメータは、リストまたは文字列を受け取ります。リストの場合は、リスト内のすべてのトークンが停止トークンとして扱われます。
==========
Prompt: 161 tokens, 296.893 tokens-per-sec
Generation: 256 tokens, 46.282 tokens-per-sec
Peak memory: 60.852 GB
```


# 備考

- 長いトークンの場合どうなるか？の検証として、[こちらのアプローチ](https://qiita.com/HikoMSP/items/705fea7af9260027a2cf)でRoo Codeでも使ってみたものの、リピート出力が発生。パラメータ調整が必要かもしれない

    以下は参考に、Markdownの修正を頼んだ時のリクエストだが、フォルダに含まれるファイルのパターンを何度も生成し続けてしまっていた

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144584/1aa16c7b-0fdd-4f21-a680-c713f428694a.png)

# 結論

- 簡単に使ってみただけだが、もう少し良い量子化版やファインチューニング版などが出てきてから試した方が良いかもしれない
- また、パラメータ調整をしてみて、うまくいったら追記します
【AWS】EC2 プレイスメントグループの種類と使い分け

# はじめに
EC2 を利用するうえで、パフォーマンスと可用性を最適化するために重要な機能の一つが **プレイスメントグループ** です。プレイスメントグループは、EC2 インスタンスの配置戦略を制御し、ワークロードの要件に合わせて最適な環境を提供します。本記事では、プレイスメントグループの基本概念、各タイプの特徴、ユースケース、注意点などを記載します。

https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/placement-groups.html

# プレイスメントグループとは
プレイスメントグループとは、EC2 インスタンスを物理的に近い場所に配置するための論理的なグループです。インスタンス間のネットワーク遅延を最小限に抑えたり、ハードウェア障害時の影響を軽減したりするために使用されます。
プレイスメントグループには、主に以下の3つのタイプがあります。

- クラスタープレイスメントグループ
  - インスタンスを低遅延かつ高スループットなネットワークで接続する必要がある場合に最適
- パーティションプレイスメントグループ
  - 大規模な分散型ワークロードにおいて、ハードウェア障害の影響を分散させる必要がある場合に最適
- スプレッドプレイスメントグループ
  - 少数の重要なインスタンスを個別のハードウェアに配置し、可用性を最大限に高める必要がある場合に最適

プレイスメントグループは任意で選択します。インスタンスをリプレイスメントグループに作成しない場合、EC2 は、関連する障害を最小限に抑えるため、すべてのインスタンスが基盤となるハードウェア全体に分散されるような方法でインスタンスを配置しようとします。

# 各プレイスメントグループの特徴と適したユースケース
プレイスメントグループごとにその特徴と適したユースケースを記載します。

## クラスタープレイスメントグループ
同じアベイラビリティーゾーン内のインスタンスを、物理的に最も近い場所に配置します。
インスタンス間のネットワーク遅延が非常に小さく、スループットが向上します。

適したユースケース:
- 高性能コンピューティング (HPC)
- 機械学習
- ビッグデータ分析
- 低遅延を要求するアプリケーション

:::note warn
クラスタープレイスメントグループは、ネットワークパフォーマンスを最適化しますが、ハードウェア障害時の影響が大きくなる可能性もあります。そのため、可用性を犠牲にしてでも EC2 インスタンス間の通信遅延を極力なくしたい場合に利用します。
:::

## パーティションプレイスメントグループ
インスタンスを複数の「パーティション」と呼ばれる論理的なグループに分割します。
各パーティションは異なるハードウェアに配置され、パーティション内のインスタンスが同時に障害の影響を受ける可能性を低減します。

適したユースケース:
- Hadoop、Cassandra、Kafka などの分散型データベース
- 大規模なウェブアプリケーション
- バッチ処理

## スプレッドプレイスメントグループ
各インスタンスを個別のハードウェアに配置します。インスタンス間の物理的な距離が最大化され、単一のハードウェア障害による影響を最小限に抑えます。

適したユースケース:
- 重要なデータベースインスタンス
- ライセンス制限のあるアプリケーション
- 高可用性が求められるアプリケーション

:::note
パーティションプレイスメントグループとスプレッドプレイスメントグループは、どちらもEC2インスタンスの可用性を向上させるための機能です。ただ、その目的と配置戦略は異なります。

パーティションプレイスメントグループは、大規模な分散型ワークロードの耐障害性を向上させるために、インスタンスをパーティションに分割して配置します。一方、スプレッドプレイスメントグループは、少数の重要なインスタンスの可用性を最大限に高めるため、各インスタンスを個別のハードウェアに配置します。

したがって、ワークロードの特性に応じて、適切なプレイスメントグループを選択することが重要です。大規模な分散型アプリケーションの場合はパーティションプレイスメントグループが適しており、少数の重要なインスタンスの可用性を高めたい場合はスプレッドプレイスメントグループが適しています。
:::

# プレイスメントグループ利用時の注意点
プレイスメントグループは、同じアベイラビリティーゾーン内のインスタンスに対してのみ有効です。
インスタンスの起動時にプレイスメントグループを指定する必要があります。後から変更することはできません。
プレイスメントグループの種類によって、起動できるインスタンスタイプやサイズに制限がある場合もあります。

# その他追加情報
プレイスメントグループの作成と管理は、AWS Management Console、AWS CLI、AWS SDK などから行うことができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318188/e614b404-bda0-4721-bbe0-e424e6f5fdc7.png)


プレイスメントグループの利用料金は無料ですが、インスタンスの料金は通常通り発生します。

# まとめ
プレイスメントグループは、EC2 インスタンスのパフォーマンスと可用性を最適化するための強力なツールです。ワークロードの要件に合わせて適切なプレイスメントグループを選択することで、アプリケーションのパフォーマンスを最大限に引き出し、可用性を向上させることができます。

# 参照
- [Placement groups for your Amazon EC2 instances](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/placement-groups.html)
GUIでぽちぽち追加するけど覚えてないと困るコマンド

# このファイルだけは必要
PyCharmを使用して、GUIでぽちぽちパッケージを追加するのですが、何を追加したかな？？？
わからないことがありました😱

昔会社員の頃にあった体験で気づいたのですが、知ってるようで忘れて毎回調べるコマンドを記事にしておきます。

思い出すためのメモです :pencil: 

本番環境にデプロイした`Dockerfile`に設定書くのですが、`requirements.txt`を自動生成するコマンドあるとありがたいなーといつも思う。

## 使用したコマンド

HTTP通信するパッケージの追加をするときにパッケージの追加するコマンドを実行
```shell
# pip install [package name]
pip install requests
```

```shell
# pip uninstall [package name]
pip uninstall requests
```

インストールしているパッケージをテキストファイルに追加するコマンド
```shell
pip freeze > requirements.txt
```

こんな感じになります。
![スクリーンショット 2025-04-07 8.27.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2303722/e6a3fc72-974e-42d5-9cb7-94cb7d922b14.png)


requirements.txtのパッケージを全てインストールするコマンド
```shell
pip install -r requirements.txt
```

requirements.txtのパッケージを全てアンインストールするコマンド
```shell
pip uninstall -r requirements.txt
```

## 最後に
Render.comやCloud Runにデプロイするときに必要な場面があったので、メモ程度ですが自分にとっては重要なコマンドなので記事にしました。
(neopixelWrite)M5StampS3、RGB LEDで遊ぶ(スタックチャンフェスで入手)


目的
----

RGB LEDを入手

結果
----

安定化


![image_original (77).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/2d4e8742-6144-4f93-ab80-c62d2120c25a.jpeg)




プログラム
----


```c++

void setup() {
  // put your setup code here, to run once:

  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);
  for(int i=0;i<2;i++){ //安定待ち
    neopixelWrite(13, 10, 10, 10); //ダミー
    delay(500);
    neopixelWrite(13, 0, 0, 0); //ダミー
    delay(500);
  }//for
  for(int i=0;i<24;i++){ //オールクリア
    neopixelWrite(13, 0, 0, 0); //ダミー
  }//for
  delay(300);
  
  //                R  G  B
  neopixelWrite(13, 5, 0, 0);
  //digitalWrite(13, LOW);digitalWrite(13, LOW);
  
  //neopixelWrite(13, 0, 5, 0);
  //digitalWrite(13, LOW);digitalWrite(13, LOW);
  
  //neopixelWrite(13, 0, 0, 5);
  //digitalWrite(13, LOW);digitalWrite(13, LOW);
  
  //NOP();NOP();NOP();
  //delayMicroseconds(1);
  //delay(1);

}

void loop() {
  // put your main code here, to run repeatedly:

  delay(3); //ダミー

}

```
memo2


```
<?php
require_once('tcpdf_include.php');

$pdf = new TCPDF('P', 'mm', 'postcard', true, 'UTF-8', false);
$pdf->AddPage();

// フォント設定
$pdf->SetFont('kozminproregular', '', 14);

// ハガキ全体の幅
$pageWidth = 100;

// --- 角丸枠 ---
$boxX = 20;
$boxY = 20;
$boxW = 60;
$boxH = 20;
$pdf->RoundedRect($boxX, $boxY, $boxW, $boxH, 3, '1111', 'D');
$pdf->SetXY($boxX, $boxY + 5);
$pdf->Cell($boxW, 10, '通知書', 0, 0, 'C');

// --- 2列4行の角丸枠（foreach 使用） ---
$texts = ['テキスト1', 'テキスト2', 'テキスト3', 'テキスト4'];
$rowH = 15;
$col1W = 30;
$col2W = 50;
$gapX = ($pageWidth - ($col1W + $col2W)) / 2;
$startY = $boxY + $boxH + 10;

foreach ($texts as $index => $text) {
    $currentY = $startY + ($index * $rowH);

    // 左列（ラベル）
    $pdf->RoundedRect($gapX, $currentY, $col1W, $rowH, 2, '1111', 'D');
    $pdf->SetXY($gapX, $currentY + 4);
    $pdf->Cell($col1W, 5, $text, 0, 0, 'C');

    // 右列（空の枠）
    $pdf->RoundedRect($gapX + $col1W, $currentY, $col2W, $rowH, 2, '1111', 'D');
}

// 出力
$pdf->Output('postcard_layout.pdf', 'I');
```
個人的備忘録：「rm -r」は強力すぎる？rmdirから学ぶ、安全志向なコマンド運用について考えてみた

## はじめに
LinuxやUnix系OSでは、ディレクトリの削除に複数の方法があります。

:::note warn
***その中でも `rmdir` コマンドは、特に「安全性」に優れた方法として知られています。***
:::

この記事では、`rmdir` の特徴や使いどころについて解説します。

## 書こうと思ったきっかけ
ディレクトリを削除する際、`rm -r` を使うと中身ごと削除されてしまうため、誤操作によるデータ損失のリスクがあります。`rmdir` はその点、安全に使えるコマンドです。

:::note info
**個人の備忘録程度の走り書きとなっておりますが、温かい目で見守っていただければ幸いです。**
:::

使い分けに迷った経験から、このテーマでまとめようと思いました。

## 結論：rmdirはこんなときに使う！
> **空のディレクトリだけを安全に削除したいとき**

## rmdir の特徴
- 空のディレクトリしか削除できない
- 誤って中身のあるフォルダを削除する心配がない
- スクリプトやCI/CD環境などでも「安全に空なら削除」処理に使える

`rmdir` は **空のディレクトリのみ** を削除できるコマンドで、`rm -r` は **中身があっても再帰的に削除** できます。
つまり、`rmdir` は **誤って重要なファイルを削除してしまうリスクが少ない** という意味で、より安全に使えるというメリットがあります。

正直、これくらいの使い所ですね...笑

**簡単に表にまとめてみた**

| コマンド   | 安全性       | 中身がある場合   | 主な使いどころ                                                 |
|------------|--------------|------------------|------------------------------------------------------------------|
| `rmdir`    | 高い         | 削除できない     | 誤削除を防ぎたいとき、空のディレクトリのみを対象にしたいとき     |
| `rm -r`    | 低い（強力） | 削除できる       | ディレクトリごと一括削除したいとき、中身も含めて完全に削除したいとき |

## 使いどころの具体例
1. **一時的に作った作業用ディレクトリの整理**
2. **Makefileやシェルスクリプトでの安全な削除処理**
3. **運用ルールとして誤削除を避けたいとき**

## rmdir の使用例
```bash
rmdir /path/to/emptydir
```

中身があると削除されないので、意図しない削除を防げます。

## まとめ
`rmdir` は「空のディレクトリを安全に削除したいとき」にぴったりのコマンドです。普段 `rm -r` を使っている方も、用途によって使い分けてみてください！
memo1

<?php
require_once('tcpdf_include.php');

$pdf = new TCPDF('P', 'mm', 'postcard', true, 'UTF-8', false);
$pdf->AddPage();

// フォント設定
$pdf->SetFont('kozminproregular', '', 14);

// ハガキ全体の幅
$pageWidth = 100;

// --- 合格通知書の角丸枠 ---
$boxX = 20;
$boxY = 20;
$boxW = 60;
$boxH = 20;
$pdf->RoundedRect($boxX, $boxY, $boxW, $boxH, 3, '1111', 'D');
$pdf->SetXY($boxX, $boxY + 5);
$pdf->Cell($boxW, 10, '合格通知書', 0, 0, 'C');

// --- 2列4行の角丸枠（foreach 使用） ---
$texts = ['テキスト1', 'テキスト2', 'テキスト3', 'テキスト4'];
$rowH = 15;
$col1W = 30;
$col2W = 50;
$gapX = ($pageWidth - ($col1W + $col2W)) / 2;
$startY = $boxY + $boxH + 10;

foreach ($texts as $index => $text) {
    $currentY = $startY + ($index * $rowH);

    // 左列（ラベル）
    $pdf->RoundedRect($gapX, $currentY, $col1W, $rowH, 2, '1111', 'D');
    $pdf->SetXY($gapX, $currentY + 4);
    $pdf->Cell($col1W, 5, $text, 0, 0, 'C');

    // 右列（空の枠）
    $pdf->RoundedRect($gapX + $col1W, $currentY, $col2W, $rowH, 2, '1111', 'D');
}

// 出力
$pdf->Output('postcard_layout.pdf', 'I');
#0097（2025/04/07） インターフェース分離の原則（Interface Segregation Principle: ISP

# インターフェース分離の原則（Interface Segregation Principle: ISP）

インターフェース分離の原則（Interface Segregation Principle: ISP）は、SOLID原則の一つであり、**「クライアントは、利用しないメソッドへの依存を強制されるべきではない」**という設計指針です。これは、特に大規模なアプリケーションや柔軟なモジュール設計において重要な原則です。本記事では、上級プログラマー向けに、PythonとTypeScriptでISPが守られている例と守られていない例を比較しながら解説します。

---

## ISPの本質

大きなインターフェースを複数の小さな特化したインターフェースに分割することで、クラスは**自分が使用しない機能を実装する義務**から解放されます。結果として、柔軟で変更に強く、保守性の高い設計が可能になります。

---

## Pythonによる例（動物の動作）

### ❌ ISPが守られていない例

```python
from abc import ABC, abstractmethod

class Animal(ABC):
    @abstractmethod
    def fly(self):
        pass

    @abstractmethod
    def swim(self):
        pass

    @abstractmethod
    def walk(self):
        pass

class Dog(Animal):
    def fly(self):
        raise NotImplementedError("Dog can't fly")

    def swim(self):
        print("Dog swims")

    def walk(self):
        print("Dog walks")
```

`Dog` クラスに不要な `fly()` メソッドの実装が強制されており、明らかに不自然です。

### ✅ ISPが守られている例

```python
from abc import ABC, abstractmethod

class Walkable(ABC):
    @abstractmethod
    def walk(self):
        pass

class Swimmable(ABC):
    @abstractmethod
    def swim(self):
        pass

class Flyable(ABC):
    @abstractmethod
    def fly(self):
        pass

class Dog(Walkable, Swimmable):
    def walk(self):
        print("Dog walks")

    def swim(self):
        print("Dog swims")

class Bird(Walkable, Flyable):
    def walk(self):
        print("Bird walks")

    def fly(self):
        print("Bird flies")
```

`Dog` や `Bird` は自身が必要とするインターフェースのみを実装し、ISPが守られています。

---

## TypeScriptによる例（ロボットの機能）

### ❌ ISPが守られていない例

```typescript
interface Robot {
    clean(): void;
    cook(): void;
    dance(): void;
}

class CleaningRobot implements Robot {
    clean(): void {
        console.log("Cleaning room");
    }
    cook(): void {
        throw new Error("Cannot cook");
    }
    dance(): void {
        throw new Error("Cannot dance");
    }
}
```

`CleaningRobot` は掃除しか行えないにもかかわらず、他の機能の実装を強制されています。

### ✅ ISPが守られている例

```typescript
interface Cleaner {
    clean(): void;
}

interface Cook {
    cook(): void;
}

interface Dancer {
    dance(): void;
}

class CleaningRobot implements Cleaner {
    clean(): void {
        console.log("Cleaning room");
    }
}

class MultiFunctionRobot implements Cleaner, Cook, Dancer {
    clean(): void {
        console.log("Cleaning room");
    }
    cook(): void {
        console.log("Cooking food");
    }
    dance(): void {
        console.log("Dancing to music");
    }
}
```

`CleaningRobot` も `MultiFunctionRobot` も、それぞれ必要な機能だけを実装しており、ISPを正しく守っています。

---

## まとめ

インターフェース分離の原則は、**過剰な依存からコードを守り、関心ごとの分離を徹底**することで、堅牢で拡張しやすいソフトウェアを実現します。上級開発者としては、抽象を扱う際に**汎用性と最小限性のバランス**を見極め、インターフェース設計を常に見直す姿勢が求められます。
ハッカソン個人備忘録③：Git pull時のエラーを解決！ローカルとリモートの分岐に対応メモ

## はじめに
Git で `pull` を使ってリモートの変更を取り込もうとした際、「divergent branches」というエラーが発生することがあります。

:::note warn
***このエラーは、ローカルとリモートのブランチの履歴が食い違っている場合に起きるもので、原因を理解して正しく対処しないと意図しない履歴の破壊などにつながる可能性もあります。***
:::

この記事では、このエラーの発生原因と対処方法について、わかりやすくまとめます。

## 書こうと思ったきっかけ
チーム開発中に Git の `pull` 操作を行ったところ、「Need to specify how to reconcile divergent branches」というエラーに遭遇しました。

最初は何が起こっているのか分からず戸惑いましたが、調べてみるとこのエラーはリモート側で強制プッシュ (`git push --force`) が行われた場合などに発生しやすいことが分かりました。

:::note info
**個人の備忘録程度の走り書きとなっておりますが、温かい目で見守っていただければ幸いです。**
:::

同じように困っている人の助けになればと思い、この記事を書くことにしました。

## Git Pull 時に発生した "divergent branches" エラーの対処法

### 背景
以下のような `git pull` 実行時にエラーが発生しました：

```bash
 ~/Desktop/next-app  (git)-[main]-  git pull origin main
Warning: Permanently added 'github.com' (ED25519) to the list of known hosts.
...
fatal: Need to specify how to reconcile divergent branches.
```

### 原因
ローカルとリモートの `main` ブランチが分岐しており、Git がそれらをどのように統合すべきか明示的な指示が必要だったためです。

ログに記載されていた以下の行：
```
+ f0d04b6...0dd3570 main -> origin/main  (forced update)
```
これは **リモートブランチが強制的に上書きされた（`git push --force` された）** ことを意味しています。

---

### 解決方法①：マージで統合したい場合
```bash
git pull --no-rebase
```
今後も毎回マージで統合したいなら：
```bash
git config pull.rebase false
```

### 解決方法②：リベースで統合したい場合
```bash
git pull --rebase
```
今後もリベース方式で統合したいなら：
```bash
git config pull.rebase true
```

### 解決方法③：fast-forward のみ許可したい場合
```bash
git pull --ff-only
```

### ローカルをリモートに合わせて強制的に上書きしたい場合（⚠️注意）
```bash
git fetch origin
git reset --hard origin/main
```
⚠️ この操作をすると、ローカルの未コミット変更や独自のコミットはすべて消えます。

---

### まとめ
- `git pull` の挙動は明示的に指定する必要があることがある
- `--rebase` を使えば履歴がきれいになりやすい
- リモートが強制更新されていた場合は特に注意が必要
- 安全に進めるならまず `git pull --rebase` を試すのがおすすめ

Git のエラーは最初こそ戸惑いますが、仕組みを理解していれば冷静に対処できます。***履歴の扱いに慣れておくことで、より安心してチーム開発を進めることができると思いました！***
ハッカソン個人備忘録②：Makefileでdocker compose execを実行したら起きたトラブルと対処法

## はじめに
Docker Compose を使って開発環境を構築していると、コンテナに入ってコマンドを実行したくなる場面がよくあります。

:::note info
**しかし、実際に `docker compose exec` を使おうとすると、意外とさまざまなエラーに遭遇することがあります。**
:::

この記事では、私が遭遇したエラーとその対処法をまとめます。

## 書こうと思ったきっかけ
ハッカソンで Next.js アプリケーションの開発を進める中、Makefile を使って簡単にコンテナへアクセスできるように設定していました。

しかし、実際に `make exec` を実行した際に、思わぬエラーが発生し、その原因と解決策を調べることになりました。

:::note warn
**個人の備忘録程度の走り書きとなっておりますが、温かい目で見守っていただければ幸いです。**
:::

同じような問題に直面する人の助けになればと思い、この記事を書くことにしました。

## Docker Composeで `exec` 時に発生するエラーの対処法

### 背景
Docker Compose を使って `next-app` コンテナに入ろうとした際、以下のコマンドを実行しました：

```bash
make exec
```

Makefile の中身は以下のようになっていました：
```makefile
exec:
	docker compose exec -it next-app bash
```

このコマンドを実行したところ、以下の2つのエラーが発生しました。

---

### エラー1：`version` 属性の警告
```bash
WARN[0000] ... the attribute `version` is obsolete, it will be ignored, please remove it to avoid potential confusion
```

#### 原因
`docker-compose.yml` に書かれている `version:` 属性が現在の仕様では不要になっています。

#### 解決策
`docker-compose.yml` の冒頭にある以下のような行を削除します：
```yaml
version: '3.8'  # ← この行を削除
```

これは警告であり、動作には支障ありませんが、今後のために削除しておくとよいでしょう。

---

### エラー2：`bash` が見つからない
```bash
OCI runtime exec failed: exec failed: unable to start container process: exec: "bash": executable file not found in $PATH: unknown
```

#### 原因
使用しているコンテナイメージに `bash` がインストールされていない可能性が高いです。
特に、Node.js の Alpine ベースイメージなどでは `bash` が入っていません。

**過去の記事**

https://qiita.com/free-honda/items/402d5b11857a28799f5a

#### 解決策
代わりに `sh`（標準シェル）を使用します。
以下のように `bash` を `sh` に変更してください：

```bash
make exec
```
Makefile の内容を以下のように変更します：
```makefile
exec:
	docker compose exec -it next-app sh
```

これにより、コンテナに問題なく入れるようになります。

---

### まとめ
- `docker-compose.yml` の `version:` は削除してもOK
- `bash` が無い場合は `sh` に切り替える
- Makefile でコマンドを簡略化しておくと便利

Docker のトラブルはよくあることなので、柔軟に対処できるようになっておくと安心です！
windows11で、sketchup6 その53

# 概要
windows11に、sketchup6を入れてみた。
rubyで、3Dを書く。
練習問題、やってみた。

# 練習問題
セレクトしたオブジェクトをグループ化せよ。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/06bc140a-094e-439c-a7fc-99dee480caa2.png)

# サンプルコード

```
def o2g
	ss = Sketchup.active_model.selection
	sents = []
	ss.each { |e|
		sents.push(e)
	}
	copy_group = Sketchup.active_model.active_entities.add_group(sents)
end

```

以上。
君たちはどう生きのびるか？2025

私見「エンジニアのキャリア論(2024)」をまとめてみました


## この出版業界の話が直球

https://qiita.com/fmlorg/items/a2e751c85112eee584dd?q=0


> ライターさんに1本5万円のギャラで、10本で50万でやってもらっていたものを、
> 「ChatGPT Pro」に月3万円課金すればできてしまう


記事の中で引用している上の文章が端的に表現しています。余計な解説は不要でしょう

同じことが全業界で進行中のはずです。業界ごとの進捗具合は予言できませんけれど、それは収集可能な学習データの量と投入された金額（開発費＋人件費）しだい



## お膝元のIT業界では？もちろん大絶賛進行中

https://qiita.com/fmlorg/items/51d28366ff29e9f93704?q=0


ただ日本は数周おくれなので、現在こういった様子を大規模観測できないかもしれません



## 大丈夫な人


たぶん、こういう人は大丈夫です。
- いろいろなことに興味をもち
- ガチャガチャ手を動かしていじくりまわしてみて
- 論理的能力/技術を抽象化して俯瞰的に見られる能力の高い人


人生、真面目に修行してきた人とでもいいましょうか。ぜひ、その路線で、あれこれ励んでほしいです



## ダメな人


- 正解をおぼえて、正解を高速検索するゲーム(試験ともいう)だけがとくい
- 答えを教えてください
- どうすれば、よい成績がつきますか？教えてください






## 対策


「大丈夫な人」になるように心がけよう！としか言いようがないのですが ...

このシリーズの最初の２つの記事は、それについて語ろうとしています。

https://qiita.com/fmlorg/items/8cad1b81f3ac3adb6fb3

https://qiita.com/fmlorg/items/5a2a35bb00174d7453ad


最初の記事では、各論として次のことを強調しています。

1. ヒマがあれば手を動かす
1. アウトプットする
1. 技術を抽象化して俯瞰的に見られるとよい

各論としては、こうなるのですが、おおまかには「場数が大事」と言ってしまうのが良いでしょう。1.と2.は場数そのものですし、3.は場数の先に初めて見えてくる何かです。



## あとがき


年度末・年度初めで忙しいのですが、授業のオリエンテーションで使おうと思い「まとめ」を準備しました。力説せずに「興味のある人は読んでください！」と紹介だけして終わりです。


## 参考文献

https://qiita.com/fmlorg/items/8cad1b81f3ac3adb6fb3

https://qiita.com/fmlorg/items/5a2a35bb00174d7453ad

https://qiita.com/fmlorg/items/a2e751c85112eee584dd?q=0

https://qiita.com/fmlorg/items/51d28366ff29e9f93704?q=0



## 初出情報

original site: https://technotes.fml.org/tech/columns/career/jobhunting-2025/

(qiita版も致命的な間違いやTYPOは修正しますがupdatesはoriginalのほうだけです)

Copyright (C) 2025 Ken’ichi Fukamachi, CC BY-NC-SA 4.0
セールスフォースいわく「(今年は)もうエンジニアを採用しません」

## (今年度は)もうエンジニアは採用しない！


2025年2月末に、セールスフォースのCEOが

> (今年は)もうエンジニアを採用しない
>
> (みんな安心しろ！AIを使い、むしろ)売上は伸びてる


という趣旨の発言をしています。

裏側では何が起こっているの？というと、次の拙記事のIT業界版でしょう。いや、むしろ、こちらのIT業界版の方が本命と言えましょう- [「箕輪さん曰く「(ChatGPTに課金すれば)現実問題、編集者はライターにお願いする必要がなくなってきました」と ...」](https://qiita.com/fmlorg/items/a2e751c85112eee584dd)

https://qiita.com/fmlorg/items/a2e751c85112eee584dd?q=0




## ITの進化=少人数で(事業を)回せる


ITが進化すればするほど「**えりすぐりの少人数だけで(事業を)回すことができる」組織が完成**していきます。

大局的に見れば、**IT業界の「ど真ん中の進化」とは「タコが自分の足をどんどん食べる」状態を完成させていくこと**です。これは、<b>「（手段を問わず）資本を増加させる」</b>ことが目的という近代資本主義の"教義"と、とても親和性が高い。この動きが止まる見込みはありません。

一方、IT業界の周辺や他業界への応用は山ほどありえて、ここがIT業界の製品/サービス最先端と言えます。でも行き着く先は、あまり変わりません。その応用が進化すればするほど、どの業界でも<b>「えりすぐりの少人数だけで(事業を)回すことができる」組織が完成</b>していきます。そこは同じはずです。もっとも「少人数」のレベルは業界によって随分ことなると思いますけれど..





## なぜか週休６日にはならない


ただ、なぜか、この手の話は「（AIのおかげで）うちは週休６日にします！その一方、売上も以前と同じ or あがっています」というオチにならないのでしょうか（それは、このオチが教義に反しているからですね？）



## あとがき

このSalesforce CEOの発言は、ネットサーフィン（死語）していて見つけたのではなく、とある講演で教えてもらいました






## 参考文献


- https://sfstandard.com/2025/02/27/salesforce-marcbenioff-layoffs-tech-agents/
   - (いろいろな記事が発見できますが ...)初出は、よくわかりません

https://qiita.com/fmlorg/items/8cad1b81f3ac3adb6fb3

https://qiita.com/fmlorg/items/5a2a35bb00174d7453ad

https://qiita.com/fmlorg/items/a2e751c85112eee584dd?q=0


## 初出情報

original site: https://technotes.fml.org/tech/columns/career/salesforce-202502/

(qiita版も致命的な間違いやTYPOは修正しますがupdatesはoriginalのほうだけです)

Copyright (C) 2025 Ken’ichi Fukamachi, CC BY-NC-SA 4.0
箕輪さん曰く「(ChatGPTに課金すれば)現実問題、編集者はライターにお願いする必要がなくなってきました」と ...

2024/12/28 の記事に、[編集者・箕輪厚介「ライターも活字メディアも淘汰され、限られた編集者だけが残る」ファンに愛される条件](https://mag.minkabu.jp/life-others/30172/)が、ありました。

https://mag.minkabu.jp/life-others/30172/

これは、拙著の記事[「機械学習を超えて生き残るためにエンジニア初心者はどうすればいいのか？」](https://qiita.com/fmlorg/items/5a2a35bb00174d7453ad)の出版業界版に相当すると言えます。**学習データが大量にあるなら、どの業界でも、おそかれはやかれ、こうなる運命**なのですが、ソフトウエア産業よりも出版業界のほうが少し早かったということでしょうか？（そんなことはありませんでした ->記事「[セールスフォースいわく「(今年度は)もうエンジニアは採用しません」](https://qiita.com/fmlorg/items/51d28366ff29e9f93704)

https://qiita.com/fmlorg/items/5a2a35bb00174d7453ad

https://qiita.com/fmlorg/items/51d28366ff29e9f93704?q=0


## 記事「『ライターも活字メディアも淘汰され、限られた編集者だけが残る』ファンに愛される条件」より


この記事の目次は「1. 2025年、ライターの仕事はなくなる可能性がある」「2. AIであればコストも時間も圧倒的に抑えられる」(以下略)です

箕輪さんは幻冬舎の有名な編集者の方です。いまは幻冬舎の子会社の取締役。売れる本をプロデュースする能力には定評がある方でしょう（実際、中の人が、どういう人なのかは、よく知りませんが、インターネット上にインタビューや対話の動画が山ほど転がっているので各自で検索し、ご評価ください）

「2. AIであればコストも時間も圧倒的に抑えられる」節の次の2ヶ所で、この記事の要点は十分わかるとおもいます

> ライターさんに1本5万円のギャラで、10本で50万でやってもらっていたものを、「ChatGPT Pro」に月3万円課金すればできてしまう


> 会社としても「もうChatGPTでやろうよ」っていう経済合理性が働いて、それまでの予算も出なくなっちゃう




## 経営的正義 vs 人を育てる


それでも（記事にあるように）旧態然な会社も多いでしょうから、2025年になったとたん、すべての会社で仕事（ライターへの発注）がなくなりはしないでしょう。ただし、裏側では、ChatGPT Proで十分いける！という会社と価格競争力で勝てないため、ライターへの発注単価は下がっていき、廃業時期を間違えたライターが路頭に迷う近未来図が見えます。もちろん新人ライターの修行の場なんて存在しません（もう新人は雇いません）

情報誌あたりなら8〜9割方、これでいけるのでしょう。いや"通り一遍"系の単行本は全部いけそうです（そもそも品質の高い原稿は量産できない（できるわけがない）ので、最近の出版数 -> 通り一遍の本が多いと推定できます）。

**会社経営としては正解です**。そのかわり大ヒットも生まれないのでしょうけれど

そして、「(a)新人は育てない(b)みんな同じサービスを使って同じような記事を書く」から、差別化が出来なくなり、出版社なんて一つあれば十分となり、出版社のともだおれが始まると思います。

ようするに10年、20年、30年先、どうするつもりなのでしょう？という話なのですが、ちかぢか廃業する気満々ならChatGPTに課金で全然OKなんですけどね



## あとがき


最近テクニカルライターの副業をしていない自分ではありますが ...感無量です ...



## 参考文献

- [インフラエンジニアのキャリアについてのポエム](https://qiita.com/fmlorg/items/8cad1b81f3ac3adb6fb3) ... Side-A
- [機械学習を超えて生き残るためにエンジニア初心者はどうすればいいのか？](https://qiita.com/fmlorg/items/5a2a35bb00174d7453ad) ... Side-B
   - この記事は、いわば Side-C です

https://qiita.com/fmlorg/items/8cad1b81f3ac3adb6fb3

https://qiita.com/fmlorg/items/5a2a35bb00174d7453ad


## 初出情報

original site: https://technotes.fml.org/tech/columns/career/writer-survival-2025/

(qiita版も致命的な間違いやTYPOは修正しますがupdatesはoriginalのほうだけです)

Copyright (C) 2025 Ken’ichi Fukamachi, CC BY-NC-SA 4.0
Geminiで忍者を描いてみた。

# 概要

Geminiで忍者を描いてみました。

# 実装

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

```
炎の技を使う忍者を描いてみてください。
```

![炎の技を使う忍者_20250407.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192024/9276bccf-9f63-4339-8da1-f2daf679f337.png)

```
氷の技を使う忍者を描いてみてください。 
```

![氷の技を使う忍者_20250407.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192024/4b2d4a53-897d-4129-95f9-726c63fe6296.png)

```
電撃の技を使う忍者を描いてみてください。
```

![電撃の技を使う忍者_20250407.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192024/7e37b799-4743-411b-a273-00b5d6ff908f.png)

```
水の技を使う忍者を描いてみてください。 
```

![水の技を使う忍者_20250407.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192024/c5544cb5-fd5d-4da9-84d0-1b7918ced6c3.png)

```
光の技を使う忍者を描いてみてください。 
```

![光の技を使う忍者_20250407.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192024/632f45e0-4df7-4c05-905e-a56639381856.png)

```
闇の技を使う忍者を描いてみてください。
```

![闇の技を使う忍者_20250407.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192024/49c3b498-3ac9-4283-a359-e7da0bf02ae1.png)

```
聖なる技を使う忍者を描いてみてください。
```

![聖なる技を使う忍者_20250407.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192024/43b813aa-cb82-44ca-9e50-62f622b7cd5f.png)

どれも興味深いです。

# まとめ

何かの役に立てばと。
Angular 属性ディレクティブについて

# 概要

Angularにはディレクティブと呼ばれる、テンプレート内の要素に対して振る舞いや見た目を追加する仕組みがある。  
ディレクティブには主に以下の2種類が存在する：

- **属性ディレクティブ**：要素の「見た目」や「振る舞い」を変更する  
- **構造ディレクティブ**：要素の「構造」（DOMの追加・削除）を制御する

> 例：  
> - 属性ディレクティブ：`ngClass`, `ngStyle`, カスタム属性ディレクティブ  
> - 構造ディレクティブ：`*ngIf`, `*ngFor`, `*ngSwitch`

構造ディレクティブは、別記事で解説している（[Angular 構造ディレクティブについて](https://qiita.com/naoki0108maeda/items/6dc20709e1b870546ea9)）。
このドキュメントでは「属性ディレクティブ」に焦点を当てて解説する。


# 属性ディレクティブとは？

属性ディレクティブは、既存の要素に「属性として追加される形」で利用される。  
HTML要素やコンポーネントの見た目、動作、状態などを動的に制御するのが主な役割。

## よく使われる組み込み属性ディレクティブ

| ディレクティブ | 説明 |
|----------------|------|
| `ngClass` | クラスを動的に付与する |
| `ngStyle` | スタイルを動的に付与する |
| `ngModel` | 双方向データバインディング（FormsModuleが必要）|

```html
<!-- ngClassの例 -->
<!-- isActive が true の場合、<div> に active クラスが付与される -->
<!-- isActive が false の場合、active クラスは付与されない -->
<div [ngClass]="{ 'active': isActive }">ボックス</div>

<!-- ngStyleの例 -->
<!-- isError が true の場合、テキストの色が赤（color: red）になる -->
<!-- isError が false の場合、テキストの色が黒（color: black）になる -->
<div [ngStyle]="{ 'color': isError ? 'red' : 'black' }">メッセージ</div>

<!-- ngModelの例 -->
<!-- ユーザーが <input> に文字を入力すると、自動的に userName に反映される -->
<!-- 同時に、userName の値が変更されれば、<input> の内容も更新される -->
<input [(ngModel)]="userName" placeholder="名前を入力">
<p>こんにちは、{{ userName }} さん！</p>
```

# カスタム属性ディレクティブの作成
自作の属性ディレクティブも作成可能。
以下は、要素の背景色を固定で黄色に変更するカスタム属性ディレクティブ。

``` highlight.directive.ts
import { Directive, ElementRef, OnInit } from '@angular/core';

// @Directive デコレーターでこのクラスがディレクティブであることを指定
@Directive({
  selector: '[appHighlight]' // テンプレートで使用する属性名（例: <p appHighlight>）
})
export class HighlightDirective implements OnInit {

  // コンストラクタで ElementRef を注入（このディレクティブが適用される要素への参照）
  constructor(private el: ElementRef) {}

  // ngOnInit は初期化時に呼ばれるライフサイクルフック
  ngOnInit() {
    // 要素の背景色を直接操作して黄色に設定
    this.el.nativeElement.style.backgroundColor = 'yellow';
  }
}
```

``` html
<!-- この段落に appHighlight ディレクティブを適用 -->
<p appHighlight>この段落の背景が黄色になります</p>
```
このコードは、カスタムディレクティブ`HighlightDirective`を作成している。
`appHighlight`属性をHTML要素に付けると、このディレクティブが適用されます。
ngOnInitライフサイクルフックで、`ElementRef`を使って要素の背景色を黄色に変更します。これにより、`<p appHighlight>`タグの背景が黄色になります。

# まとめ
Angularの属性ディレクティブは、要素の見た目や振る舞いを動的に変更する仕組みで、代表的なものに`ngClass`や`ngStyle`がある。自作の属性ディレクティブも作成可能である。
【フレーム生成】GPUをフル活用しよう。　DLSS Enabler　DLSS Swapper

フレーム生成機能を実装してみよう。
Readmeなど読みつつ進めていきましょう。
※責任は負いかねますので自己判断でお願いします。

## DLSS Enabler のインストール方法

DLSS Enablerは、本来DLSSをサポートしていないDirectX 12のゲームで、DLSSアップスケーリングとDLSS Frame Generation機能をシミュレートできるようにするツールです。主にMODとして配布されていることが多いです。具体的なインストール方法は、配布場所やバージョンによって異なる場合がありますが、一般的な手順は以下の通りです。

## DLSS Enablerの入手しよう

通常はGitHubなどのMOD配布サイトから最新版のzipファイルをダウンロードします。
信頼できるソースからダウンロードするように注意してください。
動画で紹介されている場合は、概要欄にリンクが貼られていることが多いです。
例: https://github.com/artur-graniszewski/DLSS-Enabler/releases
## 1 ファイルの展開
    1. ダウンロードしたzipファイルを展開します。
    2. ゲームフォルダへのコピーする。展開済のファイル（通常はdllファイルや設定ファイルなど）を、インストールしたいゲームの実行ファイル（.exeファイル）があるフォルダにコピー
    3. READMEファイルなどが同梱されている場合は、そちらに詳細な指示が書かれていることが多いので、必ず確認してください。


## 署名チェックの無効化 (必要な場合)
:::note info
インフォメーション
infoは省略可能です。
:::
:::note warn
確認ポイント
AMDやIntelのGPUを使用している場合、ドライバ署名チェックの無効化が必要になることがあります。
:::

展開したフォルダに「DisableNvidiaSignatureChecks.reg」のようなファイルがあれば、実行してレジストリに登録します。

## ゲームの起動と設定

ゲームを起動し、グラフィック設定などにDLSS関連の項目が表示されているか確認します。
表示されていれば、DLSSを有効にし、好みの設定を選択します。

:::note warn
注意点

DLSS Enablerは非公式なツールであるため、ゲームによっては動作しない、予期せぬ不具合が発生する、またはオンラインゲームで利用すると規約に抵触する可能性があります。

自己責任で使用してください。
最新のGPUドライバをインストールしておくことを推奨します。


インストール手順は、DLSS Enablerのバージョンや配布者によって異なる場合がありますので、必ず配布されている情報やREADMEファイルなどを確認してください。
:::


## DLSS Swapper のインストール方法
DLSS Swapperは、インストール済みのゲームで使用されているDLSS、FSR (FidelityFX Super Resolution)、XeSS (Xe Super Sampling) のdllファイルを簡単にダウンロード、管理、交換できるツールです。これにより、ゲームをアップデートすることなく、これらのアップスケーリング技術のバージョンをアップグレードまたはダウングレードできます。

## DLSS Swapperの入手:

GitHubのリリースページなどから最新版のインストーラー付きの実行ファイル（.exe）をダウンロードします。
例: https://github.com/beeradmoore/dlss-swapper/releases
インストーラーの実行:

ダウンロードした実行ファイル（例: DLSSSwapper-Setup-x.x.x.exe）をダブルクリックして実行します。
セキュリティに関する警告が表示される場合がありますが、「実行」を選択してインストールを続行します。
インストール先などを確認し、画面の指示に従ってインストールを完了させます。
## DLSS Swapperの起動

インストールが完了したら、スタートメニューから「DLSS Swapper」を検索して起動します。
## DLSSバージョンのダウンロード

DLSS Swapperの画面左側にある「Library」タブを開きます。
利用可能なDLSSのバージョン一覧が表示されるので、使用したいバージョンを選択し、「Download」ボタンをクリックしてダウンロードします。
ゲームの選択とDLSSの適用:

画面左側の「Games」タブを開きます。
DLSSを交換したいゲームが自動的にリスト表示されない場合は、「Add Game」ボタンをクリックして、ゲームの実行ファイル（.exeファイル）を選択して追加します。
リストからゲームを選択し、右側に表示される現在のDLSSバージョンを確認します。
「Swap DLSS」ボタンをクリックし、ダウンロード済みのDLSSバージョンを選択して適用します。
バージョンが正常に切り替わると、表示が更新されます。

:::note warn
注意
DLSS Swapperについて注意してください。

DLSS Swapperは、DLSSをネイティブにサポートしているゲームでのみ有効です。DLSSをサポートしていないゲームにDLSSを追加することはできません。
新しいバージョンのDLSS dllが必ずしもパフォーマンスや画質を向上させるとは限りません。場合によっては、不具合が発生することもあります。
:::

最後に。
-----
元のdllファイルはDLSS Swapperで復元できるので、安心して試すことができます。
オンラインゲームで使用する場合は、ゲームの規約を確認してください。
上記の手順で、DLSS EnablerとDLSS Swapperをインストールし、利用できるはずです。

もし不明な点があれば、それぞれのツールの配布元やコミュニティで情報を探してみることをお勧めします。

紹介した技術
------------------

Dlss Enabler

https://github.com/artur-graniszewski/DLSS-Enabler
 

DLSS Swapper

https://github.com/beeradmoore/dlss-swapper
Excelファイルの「作成者」「最終更新者」などの個人情報を一括で削除するPythonスクリプト


## 📝 はじめに

業務で共有するExcelファイルに含まれる **作成者名** や **最終更新者名** などの個人情報を削除したいことがたまにないでしょうか。  
特に、社外に提出するファイルや共有サーバーに置くファイルでは、こういった **メタデータの消し忘れ** が思わぬ情報漏えいにつながることも。

そこで、Pythonを使って、**ディレクトリ内のExcelファイル（`.xlsx`）を一括処理**し、メタデータを削除・上書きするスクリプトを作成しました。

---

## 🔧 使用ライブラリ

- [openpyxl](https://openpyxl.readthedocs.io/en/stable/)：Excelファイルの読み書きに使用

```bash
pip install openpyxl
```

## 💡 スクリプト全体
```
import openpyxl
import os

# 対象ディレクトリのパス
directory = 'your/path'

# ディレクトリ内の全ファイルをループ
for filename in os.listdir(directory):
    # .xlsxファイルのみ対象
    if filename.endswith('.xlsx'):
        filepath = os.path.join(directory, filename)
        print(f"Processing {filepath}...")

        # Excelファイルを読み込み
        wb = openpyxl.load_workbook(filepath)

        # メタデータ（プロパティ）を変更
        wb.properties.creator = 'SAMPLE'     # 作成者を指定の名前に変更（例：部門名など）
        wb.properties.lastModifiedBy = ''     # 最終更新者を空にする（削除扱い）

        # 上書き保存
        wb.save(filepath)
        print(f"Updated metadata for {filename}")

print("All files have been processed.")
```

## ✅ 処理内容のポイント
wb.properties を使って、Excelの内部プロパティを編集しています。

作成者 (creator) は任意の文字列に書き換えられます。例として「SAMPLE」としています。

最終更新者 (lastModifiedBy) は空文字を指定することで事実上の削除になります。

元ファイルを そのまま上書き保存 するので、バックアップが必要なら別途対応してください。

## ⚠️ 注意点
.xls（古い形式） には対応していません。openpyxl は .xlsx 専用です。

パスやファイル名に日本語が含まれている場合、環境によってはエンコーディングエラーが出ることがあります。

**上書き処理を行うため、事前にバックアップを取ることを強く推奨します。**

## 🎯 おわりに
ちょっとしたスクリプトですが、手作業でメタデータを確認・修正する手間が一気に省けます。
「一括で処理したい」方におすすめです。

同様のニーズがある方の参考になれば嬉しいです！
MacのWhiskyでSteamが起動しないトラブル対応について

# はじめに
2025/03/10あたりから、Windows版Steamの起動ができなくなる現象が発生している。

筆者の環境(Mac M4 OS:Sequoia 15)では動作していたが、動作しない方の報告を受けてOSのアップデート(Sequoia 15.4)を行なった結果、「Steam の起動中に予期しないエラーが発生しました (0x3008)」が発生するようになった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14053/836ce46e-2066-4639-84d5-f201dcad3ff3.png)

## フォントのインストール
Steam導入ではフォントの導入をしていなかった為、エラーメッセージの文字化け(豆腐「◻︎」)が発生していました。フォントをインストールすることで上図のエラーメッセージが表示されます。
Toolsボトルのところで「Winetricks」ボタンをクリックします。
Winetricks コマンドを実行画面のフォントタブから「cjkfonts」を選択し実行しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14053/4ed37b31-fbca-494b-8517-1cec12e87ee8.png)

## Whisky 2.3.5にアップデート
Sequoia 15.4 にすると、Whisky 2.3.4では設定画面でフリーズする現象が発生していました。
その修正パッチがマージされたため、設定画面のフリーズが解消されています。

https://github.com/Whisky-App/Whisky/pull/1345

# 対応方法
対応方法として、２パターンの方法を提示します。
筆者は最終的には、「対応2：Steam を旧バージョンに変更」の方法で対応しました。

## 対応1：「Windowsバージョン」を「Windows 7」に変更
https://www.reddit.com/r/macgaming/comments/1j8gasn/getting_this_every_time_i_try_to_open_steam_on/

Bottleの「Windowsバージョン」を「Windows 7」に変更します。

「Bottoleの設定」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14053/afd24935-646c-4408-8abf-06605dae4d4a.png)

「Windowsバージョン」を「Windows 7」します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14053/b08d0caa-5668-4848-8ff9-8bf3c4aac64d.png)

筆者の場合、Steam上に下記メッセージは表示されたものの、ドラクエ3は動作しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14053/a5b2b5e6-28b0-45a3-9a30-0d946bfe09b8.png)

ですが、報告があった方からは下記エラーで起動できなかったとのこと。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14053/9b52d3c0-3d83-40e1-b948-51d8ee45ed00.png)

## 対応2：Steam を旧バージョンに変更

https://docs.getwhisky.app/steam.html

Steamアイコンの右クリックメニューから「設定」をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14053/01a151b4-ba59-4618-97d4-b8bf53a8fafd.png)

設定画面にて引数に下記内容をセットします。これにより2025/03/06 よりの古い Steam バージョンが復元されます。

:::note alert
セキュリティ上のリスクが発生する可能性があるため、Valve では古いバージョンの Steam の実行は推奨されていません。自己責任で進めてください。
:::


```
-forcesteamupdate -forcepackagedownload -overridepackageurl http://web.archive.org/web/20250306194830if_/media.steampowered.com/client -exitsteam
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14053/01d01d38-01ba-4d9d-9bf8-ca0fc0099a78.png)

実行ボタンをクリックして Steam を起動します。
Steam の更新メッセージは表示されますが、実際には古いバージョンに更新されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14053/9259e4c2-f43f-45d1-81b8-ed87b8ba7e19.png)

Steam を一旦終了させます。
先程の引数から次の引数に変更します。

```
-noverifyfiles -nobootstrapupdate -skipinitialbootstrap -norepairfiles -overridepackageurl
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14053/c0e06f46-fbd0-4be9-93fe-9c22abcf6297.png)

実行ボタンをクリックして Steam を起動します。
Steam が起動しないようでしたら、Mac を再起動かプロセスを終了させてから Steam の起動を再挑戦してみてください。

# 最後に
この対応はあくまで暫定として、Steam、Whisky、Wineのいずれかで恒久対応してもらいトラブルなく動作するようになるといいですけどね。
Arch Linux 環境の便利コマンド＆トラブル対処Tipsまとめ

## 最初に
Arch Linuxを使っていると、ちょっとした確認やログの読み取りが非常に重要だと感じさせられたので、実際に遭遇したシーンを元に、便利なコマンドやログ解析方法などを備忘録として整理しました。
**こんなの残しておいて確認するのおそらく自分くらいですが...**

## パッケージ検索
Arch Linuxでは、pacman が標準のパッケージマネージャです。
**パッケージを検索するには？**
```
pacman -Ss <キーワード>
```
たとえば iwd を探したいときは：
```
pacman -Ss iwd
```
出力例：
```
core/iwd 2.14-1
    Internet Wireless Daemon
```
xtra や community リポジトリにあるものも同様に表示されます。

**-Q（インストール済み検索）との違いに注意すること！**
-Ss は「リポジトリ全体」から、-Qs は「インストール済みパッケージ」からの検索です。

## systemctl status でサービスの状態を確認
systemd ベースの Linux では、サービスの状態確認が超重要！
**基本的な使い方**
```
systemctl status <サービス名>
```

例：iwd の状態を確認
```
sudo systemctl status iwd
```
出力例の読み方：
* Active: active (running) → 動作中！
* Loaded: loaded (...) → 自動起動設定なども見れる
* 下部にログが表示されるので、トラブル時の手がかりになる

## lspci / lsusb でハードウェア確認
ドライバが正しく当たっていないとき、まずはデバイスの存在を確認！
**PCIデバイスの確認（主にWi-Fi, GPU など）**
```
lspci -k
```
-k を付けると、対応ドライバ情報も確認できます。

出力例：
```yaml
03:00.0 Network controller: Realtek RTL8852AE
    Kernel driver in use: rtw89_8852ae
```
→ ドライバが読み込まれているかどうか に注目！

**USBデバイスの確認（USB Wi-Fiやマウスなど）**
```
lsusb
```

出力例：
```yaml
Bus 001 Device 002: ID 0bda:c123 Realtek Semiconductor Corp. Wireless Adapter
```
dmesg コマンドでも認識ログを追うことができます。

## Wi-Fiの接続エラー解析（iwd使用時）
**エラー例1：Deauthentication event**
```
Received Deauthentication event, reason: 3, from_ap: false
```
これは「AP側から切断された」ことを示します。理由は様々：
* パスワードミス
* APが接続制限している
* セッションのタイムアウト など

**エラー例2：CMD_TRIGGER_SCAN - Network is down**
```
Received error during CMD_TRIGGER_SCAN: Network is down (100)
```
これは、**ネットワークインターフェースが "DOWN" 状態**のままスキャンしようとして失敗したエラーです。

**対処法**
1.インターフェース状態を確認：
```
ip link show wlan0
```

もし state DOWN の場合は、有効化：
```
sudo ip link set wlan0 up
```

2.デバイスが有効か確認：
```
rfkill list
```
Wi-Fiがブロックされているときは解除：
```
rfkill unblock wifi
```
3.自動接続状態をリセットする場合：
```
iwctl
[iwd]# station wlan0 disconnect
[iwd]# station wlan0 connect <SSID>
```
## まとめ

| コマンド | 用途 |
|:-----------|------------:|
| pacman -Ss | パッケージをリポジトリから検索 |
| systemctl status | サービス状態の確認 |
| lspci -k / lsusb | ハードウェアとドライバ確認 |
| journalctl -u iwd | iwd関連のログを表示 |
| left       | right       |
| ip link, rfkill | ネットワーク有効化 |

## 最後に
Linuxは自由な反面、ちょっとした操作やログ読みの力が求められる気がします。
逆に言えば「問題が起きたときに、自分で調べて解決できる力」が付きやすくもあるのかな（あればいいな）。
CloudFrontの署名付きCookieと署名付きURLの違い

CloudFrontの署名付きCookieと署名付きURLの主な違いは、アクセス制御の方法とユースケースにあります：

### 署名付きURL

1. **動作方式**：
   - 各リソース（ファイル）に対して個別のURLを生成
   - URL自体に認証情報が含まれる
   - 例：`https://d1234.cloudfront.net/images/photo.jpg?Expires=1598888000&Signature=abc123...`

2. **ユースケース**：
   - 特定のファイルへの一時的なアクセス提供
   - ダウンロードリンクの共有
   - 個別のコンテンツごとに異なるアクセス権限が必要な場合

3. **制限**：
   - 各ファイルごとに別々のURLが必要
   - URLが長くなりがち
   - キャッシュの問題が発生する可能性あり（クエリパラメータが異なるため）

### 署名付きCookie

1. **動作方式**：
   - ブラウザにCookieを設定し、そのCookieを使って複数リソースへのアクセスを許可
   - CloudFrontにリクエストを送る際に自動的にCookieが送られる
   - 一度認証されると、指定したパターンの全リソースにアクセス可能

2. **ユースケース**：
   - 保護された一連のファイル（例：会員サイトのコンテンツ全体）へのアクセス
   - ユーザーが複数のファイルにアクセスする必要がある場合
   - HLSビデオストリーミングなど、多数の小さなファイルへのアクセス

3. **利点**：
   - 一度設定すれば複数のファイルにアクセス可能
   - URLは変更されない（標準のCloudFront URL）
   - キャッシュ効率が良い

### 実際の違い（技術的な観点）

1. **スコープ**：
   - 署名付きURL：単一のファイルに対して有効
   - 署名付きCookie：パターン（例：`/members/*`）に一致する全てのファイルに有効

2. **実装場所**：
   - 署名付きURL：URLを生成してユーザーに提供
   - 署名付きCookie：サーバーサイドでCookieを設定する必要がある

3. **ブラウザの互換性**：
   - 署名付きURL：全てのクライアントで動作
   - 署名付きCookie：Cookieをサポートするブラウザのみ

4. **URLの長さ**：
   - 署名付きURL：署名情報がURLに含まれるため長くなる
   - 署名付きCookie：標準のURLを使用


多くの場合、実際のシステムでは両方の技術を状況に応じて使い分けることがベストプラクティスです。