OmniAICreator/Qiita-1.07M huggingface dataset:
【メモ】データ活用のためのデータ整備


[書籍：実践的データ基盤への処方箋](https://www.amazon.co.jp/dp/4297124459)
第1章「データ活用のためのデータ整備」のメモです。

#### ▪️全体の流れ
１、ユースケース、そのためのデータ活用方法を検討
２、そこから逆算する形でデータ収集、整備の投資判断を行う

データ基盤の担当者はビジネスとデータを繋げることを意識しよう
思考の多くをユースケースに充てよう

#### ▪️データの流れ
データソース
↓
データ収集
↓
データレイク
↓
データウェアハウス
↓
データマート
↓
ユースケース

・入り口（データソース）と出口（ユースケース）を洗い出す
・思考の順番（ユースケースから考える）とは異なるので、あくまでデータ自体の流れとして捉える

#### ▪️入り口と出口をマッピングする方法
誰がどのデータに対して、どのような処理を行うのかをCRUD表を作成して管理
・Create
・Read
・Update
・Delete


#### ▪️用語集をまとめる
人によって言葉の捉え方が異なるので定義を取り決める
（例：売上とは税込か否かなど）

#### ▪️データソースの品質にはこだわる
・データが取れない、誤っていると分析に繋げられないため
→下流から上流へフィードバックすると良い

#### ▪️データの生成過程を知る
・例：売上はデータベースと銀行振込履歴どちらを採用すべきか
→両方見る
理由；データベースは障害の可能性があり、銀行振込は購入日から時差がある可能性あり、それぞれ一長一短なため

#### ▪️データベースの詳細を把握するために
ER図を描こう

#### ▪️データソースの生成過程を業務レイヤで整理しよう
|データ生成の現場|例|
|---|---|
|ロール|顧客|
|オペレーション|スマホから購入ボタンクリック|
|アプリケーション|ECサイト|
|ストレージ|データベース|

これをもとに現状と理想のギャップを把握
→原因と改善案を考える

データ生成者とデータ活用者では利害が一致していない
・データ生成者：商談に集中したいので紙のメモが良い
・データ活用者：データ分析しやすい形で保存してほしい
解決案：
・議論をする場を作る
・解決したいと思える状態作り（例：インセンティブ設計）
・簡単に解決できる環境作り（例：ツールの導入）


#### ▪️マスターデータの整備
同じものを指すのに部署によって使っている言葉が異なる場合がある
→社内に周知の上、部署横断のマスターデータを整備しよう

#### ▪️商品IDを生成しよう
似た商品名を一緒にしてしまう or 同じ商品なのに分けてしまうといったことを防ぐ
→全社共通の商品IDを作成する

#### ▪️履歴データを生成しよう
データを上書きした場合、後で確認する必要が出てきた際や、分析の観点で新旧を比較したい際に困る。
→履歴テーブルを持つなど履歴を管理しよう。

#### ▪️データレイク
・データレイクはデータをそのままコピーするだけ。無闇に加工したり集計したりしてから入れない。
・データレイクは1つだけ。複数あると混乱の元となる

#### ▪️データウェアハウス
・分析用DB
・部門横断の共通指標はデータウェアハウスで管理する
・指標は全社で定義を統一させる。

#### ▪️データウェアハウス層の作り方

１、データクレンジング：できるだけデータウェアハウスの段階で行う
２、スタースキーマの作成：ファクトテーブル＋ディメンションテーブル
３、共通指標の作成

データウェアハウスを作るタイミング
→一番最後

まずは両端を充実させる
・データソース→データレイク
・ユースケース→データマート
ある程度使い道が見えてきたらデータウェアハウスに落とし込む


#### ▪️データマート
・ユーズケースごとに作る
・データマートが充実してきて、業務知識が体系化されてきたらデータウェアハウスを作る
・データウェアハウスとデータマートの依存関係を１つのワークフローエンジンで管理する

・データマートが散乱し出したら
解決策：
・クリーニングの仕組みを全社で作る
・２つのステップでデータマートを作るようにする
１、とりあえずBIツール、Excelなどで集計する
２、データ活用が運用に乗ったらデータマートを作る

#### ▪️ユースケース
・データの利用状況の解像度を上げよう
→5W1Hで考える

・データを活用してもらうために
→部署によって使い慣れているツールが異なる（BIツール、Excel、SQLなど）
→自分の都合でツールを押し付けるのはよそう

#### ▪️メタデータ
このデータはどのようなデータかという情報を持つデータ

・メタデータを管理して、データの調査コストを減らそう
・メタデータの管理は、分析用DBやメタデータ管理ツールでできる
・メタデータの管理に最も適しているのはデータ生成者
・更新が追いつかないなどの困難さを伴うので、協力してもらえるような関係作りが必要

#### ▪️サービスレベル
サービスの品質水準

以下のサイクルを回して改善していく
・目標設定
・関係者との合意
・現状の計測
・課題の特定
・必要な施策の実施
・結果の振り返り

品質のコントロールをしよう
・過剰な品質要求はデータ整備の負担が増すばかりである
→全てのデータを対象にするのではなく、実際に計測が必要なデータの種類はどれかを検討しよう


#### ▪️データスチュアード
データマネージャと呼ばれることもある。
役割：
・データの問い合わせ対応
・データ整備の推進

**データ整備推進の流れ：**
問い合わせの対応
↓
要望（ユースケース）の把握
↓
サービスレベルの定義
↓
メタデータで計測
↓
目標と現状を把握し、解決策を検討
↓
データ生成者と協力しデータソースを整備
必要に応じて、データレイク、データウェアハウス、データマートを整備
アクセス許可境界(Permissions Boundary)を編集させないポリシー

# はじめに

IAMはいじらせたいけど、アクセス許可境界(Permissions Boundary)までは触らせたくない、というケースに対応できそうな方法を考えてみました。

# 概要

以下の禁止が含まれるポリシーを作成し使います。

- すべてのロールに対して、アクセス許可境界の設定・削除の禁止
- すべてのユーザに対して、アクセス許可境界の設定・削除の禁止
- アクセス許可境界として使うポリシーの、編集の禁止
    - 対象のポリシーには、専用のタグを付与しておきます

:::note warn
すべてのロール・ユーザのアクセス許可境界が修正できないようにしています。
自身に宛がわれているのみ対象とする場合は、`Resource`を直に指定すればよいかと思います。
:::


# 参考

https://docs.aws.amazon.com/ja_jp/service-authorization/latest/reference/list_awsidentityandaccessmanagementiam.html

# 作成するポリシー
以下のCloudFormationテンプレートを作成し、その後コンソールなどからタグ`Boundary:True`を付与します。CloudFormationからはマネジメントポリシーにタグは付与できないようですので、別途付与します。

```yaml:createDenyPermissionBoundaryEdit.yaml
AWSTemplateFormatVersion: '2010-09-09'
  
Resources:
  PolicyDenyPermissionBoundaryEdit:
    Type: 'AWS::IAM::ManagedPolicy'
    Properties:
      ManagedPolicyName: 'DenyPermissionBoundaryEdit'
      Path: /
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Deny
            Action: 
              - 'iam:PutRolePermissionsBoundary'
              - 'iam:DeleteRolePermissionsBoundary'
            Resource: !Sub "arn:aws:iam::${AWS::AccountId}:role/*"
          - Effect: Deny
            Action: 
              - 'iam:PutUserPermissionsBoundary'
              - 'iam:DeleteUserPermissionsBoundary'
            Resource: !Sub "arn:aws:iam::${AWS::AccountId}:user/*"
          - Effect: Deny
            Action: '*'
            Resource: !Sub 'arn:aws:iam::${AWS::AccountId}:policy/*'
            Condition:
              StringEquals:
                aws:ResourceTag/Boundary: 'True'
          - Effect: Allow
            Action: '*'
            Resource: '*'
      # ManagedPolicyでは定義できないが、忘れないようにコメントアウトして記載
      # Tags: 
      #   - Key: 'Boundary'
      #     Value: 'True'
```

許可ポリシーは全権限を与えています。必要に応じて最小の権限を付与ください。

# 動作確認

先のポリシーを、対象のアクセス許可境界として宛がいます。

ユーザにアクセス許可境界を宛がおうとしますが、禁止されているため失敗します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/d4d33c5b-5443-4842-ab64-dbd94958a8bc.png)

自分のアクセス許可境界も変更できません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/32c506c2-be64-474f-ab84-881be20e7704.png)

ロールも同様に、アクセス許可境界の設定が禁止されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/451f85cd-7ccc-42d1-9776-e838285f2107.png)

アクセス許可境界用としてつけているタグがあるポリシーの編集もできません。そのため、自身のアクセス許可境界の禁止を緩めることもできません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553680/7c98d361-b9c9-4fa1-b281-defeae81bcd4.png)

# おわりに

今回はアクセス許可境界を変更させないポリシーを考えてみました。運用担当に一部IAM編集のみさせる、という場合に使えるかと思います。

この記事がどなたかのお役に立ちましたら幸いです。
Docker Desktopのアップグレード時にMcAfeeサービスが原因でエラーが出た時の対処法

# Docker Desktopのアップグレード時にMcAfeeサービスが原因でエラーが出た時の対処法

## 概要

**Docker Desktop 4.29.0** から **Docker Desktop 4.40.0** へアップグレードしようとしたところ、次のようなエラーが表示され、インストールが進まない事象が発生しました。

The following applications must be closed to continue installing Docker Desktop:
McAfee Frame Host (service)

Dockerのインストーラーが、**McAfeeの常駐サービス（Frame Host）を停止できない**ためにブロックされてしまっているようです。  
しかし、**McAfeeを一時的に無効化する方法**を使えば、アップグレードが可能です。

本記事ではその手順を紹介します。

---

## 対処法（自己責任で）

### 1. レジストリエディタを起動

`Win + R` → `regedit` → Enter

次のパスに移動します：

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\mc-fw-host


### 2. `Start` の値を変更

- `Start` という名前のDWORD値を探します。
- 私の環境では **初期値が「2」** になっていました。
- これを **「4」** に変更します。

| 値 | 意味 |
|----|------|
| 2  | 自動起動 |
| 4  | 無効化（起動しない） |

### 3. PCを再起動

これにより、`mc-fw-host` サービスが起動しなくなり、Docker Desktopのインストーラーにブロックされなくなります。

### 4. Docker Desktopをアップグレード

ここでの作業はMacafeeが起動していないので、短時間ですませます。  
Docker Desktopをアップグレードインストールします。正常にインストーラーが進み、Docker Desktop 4.40.0 にアップグレードできました。

### 5. レジストリを元に戻す

アップグレード後、レジストリエディタを開いて `Start` の値を **元の値（例：2）** に戻します。

### 6. PCを再起動

McAfeeの保護機能が元通りになっていることを確認します。

---

## 注意点

- この方法はMcAfeeの一部機能を一時的に無効化するものであり、**セキュリティリスクが伴う可能性**があります。
- 実施は**自己責任**でお願いいたします。

---

## おわりに

Dockerのアップグレードがセキュリティソフトによって阻害されるケースは他にもあるようです。  
このような回避策を知っておくと、トラブル時にも落ち着いて対応できます。

同様の事象に遭遇した方の参考になれば幸いです。
Docker Desktopのインストール

# Dockerメモ

Dockerについて分かりずらくなっているので整理。

Docker Desktop 　商用利用では費用がかかる。
Docker Engine　　無償

Windowsで使うならDocker Desktopを使うのが良さそう。
WSL上のUbuntuにDockerをインストールして使うこともできるようだが、Docker Desktopを使うのが最もよさそう。

https://www.docker.com/products/docker-desktop/

Download for Windowsをクリック
Docker Desktop Installer.exeを起動

Installerでデフォルト設定のままインストールを実行
lftpで “Fatal error: Certificate verification: The certificate is NOT trusted. The certificate issuer is unknownが出た時の対処法

### 状況の説明
OpenSSLで作成した証明書が、証明書の検証でエラーになる。

* AWSで (EC2) は、ACMの証明書をロードバランサに登録してhttpsに使用している。

* 上記のEC2インスタンスでFTPSを設定 (こっちは OpenSSL で自己署名証明書を利用している）しているときにこのエラーが発生。

* WSLからlftpというFTPクライアントツールを使用してパッシブモードで接続。FTPの宛先のグローバルIPアドレスの指定や、ポートの解放 (クライアント側のufw、サーバー側の Firewalld、EC2のセキュリティグループのインバウンドルール）は既におこなっている。

* FTPSの暗号化は、Expicitモードを使用 (コントロールコネクションに使用するポート番号は 21）。

### 環境
ローカルOS: WSL (`Ubuntu-24.04`)
リモートOS: Amazon Linux 2023

``` .bash
# WindowsのPowerShellでUbuntu (WSL)にログイン
wsl -d Ubuntu-24.04
```


## 仮説
ACMの証明書と、OpenSSLの証明書が干渉している

### 根拠
Googleで "the certificate issuer is unknown"という検索キーワードで以下のSalesForceの製品トラブルシューティングが出てきます。
> Cause
証明書信頼リスト (CTL) と認証機関 (CA) の証明書のダウンロードが競合により妨げられています。そのため、Windows では licensing.tableau.com の SSL 証明書が有効で信頼できる証明書であることを確認できません。

クライアント側で証明書 (今回は自己署名CAが発行したもの）のダウンロードが競合している、ということかもしれません。エラーメッセージの "The certificate issuer" といっているのは、この自己署名CAである可能性が高いです。


**参考**

https://help.salesforce.com/s/articleView?id=001473545&type=1


## 応急処置的な対応
lftpの設定ファイルで、以下のように`ssl:verify-certificate`の値を`false`（証明書を検証しない）にすればとりあえずエラーは出なくなります。これによって、（おそらくFTPのコントロールコネクションの前におこなわれている、）FTPSに使用する SSL証明書を検証をスキップできます。

``` /etc/lftp.conf
set ssl:verify-certificate false # 自己署名証明書 (個人的な利用に限る)のため、検証をしない
```

ただし、自己署名証明書やサーバー証明書を検証しなくなります。自己署名証明書の場合はこの対応でとりあえずはOKということにします。
[ABC405] ABC 405(Atcoder Beginner Contest)のA~D(A,B,C,D)問題をPythonで解説(復習)

# [ABC405] ABC 405(Atcoder Beginner Contest)のA~D(A,B,C,D)問題をPythonで解説(復習)

# A問題
- `X` によって分岐する。
- `WYSIWYG` ですね（）。
```A.py
"""
<方針>
- `X` によって分岐する。
- `WYSIWYG` ですね（）。
"""
# 入力
R, X = map(int, input().split())

# Div1
if(X == 1):
  if(1600 <= R <= 2999):
    print("Yes")
  else:
    print("No")

# Div2
elif(X == 2):
  if(1200 <= R <= 2399):
    print("Yes")
  else:
    print("No")
```

# B問題
- `.pop()` を使って、末尾の要素を消していく。
- 逐一全ての整数を含むかを確認する。
```B.py
"""
<方針>
- `.pop()` を使って、末尾の要素を消していく。
- 逐一全ての整数を含むかを確認する。
"""
# 入力
N, M = map(int, input().split())
A = list(map(int, input().split()))

# popで要素を消していく。
for cnt in range(N+1):
  # 要素が存在するかを管理
  exists = [False]*(M+1)
  for a in A:
    exists[a] = True
  
  # 1~Mまで全ての要素があれば、
  if all(exists[1:]):
    # 末尾を消す
    A.pop()
  # 消えていれば、終了する。
  else:
    break

# 出力
print(cnt)
```

# C問題
## 方針
- `O(N^2)` はダメそう。なんとか `O(N)` 程度で終わらせる必要がある。
- `A` をフルメッシュに掛け合わせたものから、自分自身の２乗を引いて、半分にすれば問題なさそう。
  - `{ (a_1 + a_2 + ... + a_n)^2 - (a_1^2 + a_2^2 + ... + a_n^2) }/2`
## 前提
- `C`問題あたりで，`TLE`になる人は，制約条件を見る癖をつけよう．
- `A`と`B`問題では，基本的に制約条件を見ずにやっても解ける．
- しかし，`C`問題以降では，制約条件を見ないと必ず`TLE`すると思っても良い．
- 詳しい話は私の[352回の記事](https://qiita.com/mattsunkun/items/837444254f03e6105922) の`C`問題の解説に記したので，是非参照してほしい．
```C.py
"""
<方針>
- `O(N^2)` はダメそう。なんとか `O(N)` 程度で終わらせる必要がある。
- `A` をフルメッシュに掛け合わせたものから、自分自身の２乗を引いて、半分にすれば問題なさそう。
  - `{ (a_1 + a_2 + ... + a_n)^2 - (a_1^2 + a_2^2 + ... + a_n^2) }/2`
"""
N = int(input())
A = list(map(int, input().split()))

# フルメッシュ
full_mesh = sum(A)**2

# 自分自身の２乗
sum_square = sum([a**2 for a in A])

# 答え
ans = (full_mesh - sum_square) // 2

print(ans)
```

# D問題
- `BFS` して、どのマスの方向から来たかを塗れば良さそう。
```D.py
"""
<方針>
- `BFS` して、どのマスの方向から来たかを塗れば良さそう。
"""
from collections import deque

# 入力
H, W = map(int, input().split())
SS = [list(input()) for _ in range(H)]

q = deque()

# スタート地点を登録
for i in range(H):
  for j in range(W):
    if(SS[i][j] == "E"):
      q.append([i, j])

while q:
  i, j = q.popleft() # BFS
  
  # 次をみる
  for di, dj, x in [
    [0, 1, ">"], 
    [0, -1, "<"], 
    [1, 0, "v"], 
    [-1, 0, "^"], 
    ]:
      I = i-di
      J = j-dj
      # 枠内
      if(0<=I<H and 0<=J<W):
        # まだ道が決まってない
        if(SS[I][J] == "."):
          # 道を決める
          SS[I][J] = x
          # 次を格納
          q.append([I, J])

# 出力
for S in SS:
  print("".join(S))
```

# 補足
### 関係するリンク(参考文献など)
- [今回のコンテスト](https://atcoder.jp/contests/abc405)

### 筆者について
- [Atcoderアカウント](https://atcoder.jp/users/mattsunkun)
- *今回も不参加のため，成績なし．*
- [解説で示したA問題の提出](https://atcoder.jp/contests/abc405/submissions/65718251)
- [解説で示したB問題の提出](https://atcoder.jp/contests/abc405/submissions/65718586)
- [解説で示したC問題の提出](https://atcoder.jp/contests/abc405/submissions/65718698)
- [解説で示したD問題の提出](https://atcoder.jp/contests/abc405/submissions/65718983)
### その他
- **間違いを含んでいる可能性があります．**
- 方針と言いつつ，方針ではない感想などを書いている可能性があります．
- A問題から解説がだんだん省略されます．
- コードに書かれている解説の文言と，その上に書いてある解説の文言を変えている場合があります．
### 最後に一言
- 友人（@hamao）が[面白いもの](https://x.com/hamao_0820/status/1919733011584557115)を作ってます。よければ使ってみて。
PMP®資格 更新ガイド

# PMP®資格 更新ガイド：3年ごとの手続き

PMP® (Project Management Professional) 資格を維持するためには、3年ごとの更新が必要です。

## 1. PMP®更新の基本：CCRサイクルと必要PDU

* **CCR (Continuing Certification Requirements) サイクルとは？**
    * PMP®資格の有効期間は**3年間**です。この期間を「CCRサイクル」と呼びます。
    * このサイクル内に所定の要件を満たすことで資格が更新されます。

* **必要なPDU (Professional Development Units) 総数**
    * 更新には、3年間で**合計60 PDU**の取得が必要です。
    * PDUは、学習や専門活動を通じて得られる単位で、通常1 PDU = 1時間に相当します。

## 2. PDU取得のポイント：2つのカテゴリとタレントトライアングル

PDUは「Education (教育)」と「Giving Back (専門職への還元)」の2つのカテゴリに大別されます。

* **カテゴリ1：Education PDU (教育)**
    * **必須PDU数：最低35 PDU**
    * **PMI Talent Triangle® (タレントトライアングル) に沿った学習が必須**です。各分野で**最低8 PDU**を取得する必要があります。
        * **Ways of Working (働き方): 最低8 PDU**
            * 内容：アジャイル、ウォーターフォール、リスク管理、スケジュール管理など、プロジェクトマネジメントの技術的側面。
            * (旧称: Technical Project Management)
        * **Power Skills (パワースキル): 最低8 PDU**
            * 内容：リーダーシップ、コミュニケーション、交渉、問題解決、チームビルディングなど、プロジェクトを導く対人スキル。
            * (旧称: Leadership)
        * **Business Acumen (ビジネス感覚): 最低8 PDU**
            * 内容：業界知識、戦略的思考、ビジネス分析、法令順守など、プロジェクトと組織戦略を結びつけるスキル。
            * (旧称: Strategic and Business Management)
    * タレントトライアングルの上記3分野で合計24 PDU (8 PDU × 3) を取得後、残りのEducation PDU (35 PDU - 24 PDU = **11 PDU**) は、タレントトライアングルの**いずれの分野からでも取得可能**です。

* **カテゴリ2：Giving Back to the Profession PDU (専門職への還元)**
    * **最大PDU数：25 PDUまで**
        * このカテゴリからのPDU取得は必須ではありません (Education PDUのみで60 PDUを取得することも可能です)。
    * 主な活動例：
        * **実務経験 (Working as a Practitioner):** プロジェクトマネージャーとしての実務 (最大8 PDUまで)
        * **ボランティア活動**
        * **知識創造** (記事執筆、プレゼンテーションなど)
        * **その他** (メンタリング、非公式な学習など)

## 3. PDUの具体的な取得方法

* **Education PDU の主な取得方法**
    * PMIや認定トレーニングプロバイダー (ATP) のコース・研修
    * PMI支部やオンラインコミュニティのイベント・ウェビナー
    * 大学等のプロジェクトマネジメント関連コース
    * 書籍や記事による自己学習
    * 業界カンファレンスやセミナーへの参加

* **Giving Back PDU の主な取得方法**
    * プロジェクトマネージャーとしての実務
    * PMI支部でのボランティア
    * プロジェクトマネジメントに関する記事執筆、講演
    * メンタリング活動

## 4. 更新手続きの流れ：PDU報告から更新完了まで

1.  **PDUの記録・報告:**
    * 取得したPDUは、PMIのオンラインCCRシステム (CCRS) を通じて随時報告します。
2.  **更新申請:**
    * 60 PDUを取得後、CCRサイクル終了前にPMIウェブサイトから更新を申請します。
3.  **更新料の支払い:**
    * PMI会員: 通常 **\$60 USD**
    * PMI非会員: 通常 **\$150 USD**
    * ※料金は変動する場合があるため、PMI公式サイトで最新情報をご確認ください。
4.  **資格更新の確認:**
    * 手続き完了後、PMIから通知があり、新しいCCRサイクルが始まります。

## 5. 押さえておきたい注意点

* **PDUの持ち越し:**
    * CCRサイクル中に60 PDUを超えて取得した場合、**最大20 PDU (Education PDUのみ)** を次のサイクルに持ち越せます (ただし、3年目のサイクルで取得したPDUに限る)。
* **更新期限とペナルティ:**
    * CCRサイクル終了日までに更新を完了してください。
    * 期限を過ぎると資格が「停止 (Suspended)」となり、1年間の猶予期間内に更新しないと「失効 (Expired)」となります。
* **監査について:**
    * PMIはPDU申請の監査をランダムに行います。監査対象となった場合、PDU取得の証明書類が必要です。関連記録は必ず保管しましょう。

## 6. 最後に：最新情報の確認を忘れずに

PMP®の更新要件は変更されることがあります。必ず**PMIの公式サイト**で最新の情報を確認してください。

* **PMI公式サイト:** [https://www.pmi.org/](https://www.pmi.org/)
* **CCRハンドブック (Continuing Certification Requirements Handbook):** PMI公式サイトからダウンロード可能です。PDUカテゴリや申請方法の詳細が記載されています。

計画的なPDU取得と早めの更新手続きで、PMP®資格を有効に活用しましょう。
リーダブルコード（第3章〜第5章）の学び

## はじめに
今回は、第3章〜第4章を通して学んだことを整理します。

第1章〜第2章でのメッセージは、
「コードを理解するための時間を最大限に短縮させるために、クリアなイメージができる名前をつけろ」
だと思っていて、第3章では具体的な命名方法について書かれていました。

第4章ではコードの「レイアウト（視覚的な整列）」、
第5章ではコメントの書き方について書かれていました。

その中でも、特に今の自分にとって必要だと感じたポイントを整理します。


## 第3章での学び
* `limit` のような曖昧な単語ではなく、`max` や `min` を使って、範囲の意図を明確にする。
* 包含的／排他的な範囲を表すときは、`start` や `end` よりも、`begin` や `end` を使う方が一般的。

## 第4章での学び
* 意味の近いコードは、縦に整列させることで一目で関係性がわかる。

## 第5章での学び
* コメントには、「自分の考えたこと」を残す。そうすることで、他の人が同じことを再び考える必要がなくなる。
* コードの欠陥にはコメントを付ける。

| 記法   | 意味                               |
|--------|------------------------------------|
| TODO   | 後で手を付けるべき箇所            |
| FIXME  | 既知の不具合があるコード          |
| HACK   | あまりきれいじゃない解決策         |
| XXX    | 危険！重大な問題がある箇所         |

* 定数が必要な背景や理由がわかりづらいときは、コメントを残す。
* プロジェクトにはじめて参加する人が疑問に思うであろうことをあらかじめコメントに残しておく。

## 終わりに
様々な方法論を学んだが、最も大切なことは
「コードを読む人の立場になること」
これに尽きるのではないかと思った。

そこには「想像力」と「工夫」が必要だと思う。
正直こういったことはちょっと手間だなと思ってしまうが、大切なことはだいたい面倒くさい。
だから、日々意識して習慣化させてしまおうと思う。
【合格体験記】JSTQB認定テスト技術者資格 Foundation Level試験 (シラバス2023 V4)

2025年5月7日にJSTQB FLを合格しました。
2週間ほど(12日間)の学習で合格したので当時の学習方法を共有します。
# 結論
私はJSTQB Foundation教科書＆問題集 シラバス2023対応の読み込み、付属の模擬問題とテス友での学習で合格しました。

# 受験のきっかけ
テスト業務を2年ほど従事していますが何となくの雰囲気でテストしている感があったのでテストに対する一般的な知識を学んでみようと思い受験しました。

# 試験概要
試験の概要・問題数と合格の目安は以下の通りです。

試験時間：60分
問題数：40問
出題形式：4択から選択
合格基準：正解率 65%以上（26問正解が目安）
合格率：約60％
費用：22,000円(税込)
試験は2022年度よりCBT（コンピュータ・ベースト・テスティング）にて実施。

シラバスは 6つの章で構成されています。試験はシラバスに沿って出題されます。

各章の内容と必要な学習時間の目安は以下の通りです。

1 章　テストの基礎（学習時間175分）
2 章　ソフトウェア開発ライフサイクル全体を通してのテスト（学習時間100分）
3 章　静的テスト（学習時間135分）
4 章　テスト技法（学習時間330分）
5 章　テストマネジメント（学習時間225分）
6 章　テスト支援ツール（学習時間40分）

# 実際の学習方法
まず以下の対策書を2周ほど章末問題も解きながら読み込みました。

https://www.amazon.co.jp/%E5%BE%B9%E5%BA%95%E6%94%BB%E7%95%A5-JSTQB-Foundation%E6%95%99%E7%A7%91%E6%9B%B8%EF%BC%86%E5%95%8F%E9%A1%8C%E9%9B%86-%E3%82%B7%E3%83%A9%E3%83%90%E3%82%B92023%E5%AF%BE%E5%BF%9C-%E6%A2%85%E7%94%B0/dp/4295020192/ref=pd_lpo_d_sccl_1/357-4581444-7458234?pd_rd_w=GaKLn&content-id=amzn1.sym.855d8f70-df76-4181-80b0-56e48ae3bb9b&pf_rd_p=855d8f70-df76-4181-80b0-56e48ae3bb9b&pf_rd_r=S1JX6P95QGK29Z8DRKAQ&pd_rd_wg=mU0lR&pd_rd_r=1f49841d-93e6-48f7-85cc-c5b37a0616ae&pd_rd_i=4295020192&psc=1

こちらはJSTQB認定テスト技術者資格 Foundation Level試験の最新シラバス（2023年版）に準拠したテキスト兼問題集です。章末には10問程度の問題があり理解度をチェックすることができます。また本の終盤には模擬試験と同等の40問の模擬試験があり試験の雰囲気をつかむことができます。

学習の初期段階でシラバスでは実務でのイメージが付きづらく本書を立ち読みした際にシラバスの内容を分かりやすくかみ砕いた表現、具体例を交えた解説に気に入り購入しました。
そのため私はシラバスはほとんど読んでおらずこちらでのインプットをメインに学習を進めました。

2周の読み込み(15時間程度精読)が終わってからテス友での学習を開始しランダム40問を解き72％程度の正答率でした。

https://www.qbook.jp/info-testomo/

さらに2周読み込みテス友の正答率が9割超えました。

![IMG_1386.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4084188/e94d538f-faec-4ab8-987e-a4f4ac78f091.jpeg)

最終的にテス友は40問通してを5回、10問ランダムを6回学習しました。

合計学習時間は30.9hでした。

![IMG_1385.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4084188/796127a9-65d4-4a2c-ab9d-f809204186ad.jpeg)

↑はスマホアプリの「集中」で記録しました。ポモドーロ法を用いて学習できます
https://bondavi.jp/products/shuchu

結果として9割インプット1割問題演習といった学習になりました。

# 受験を終えて
全体的に試験の難易度は想像していたよりも難しかったです。
理由としてはテス友のような知っていれば解けるようなものがあまりなく具体的な場面からどう解決するかどれが最善なものかを選ぶ問題が多く数問ひっかけ問題のようなものも出たためです。
私は対策本で学習したのでイメージが容易だったため問題ありませんでしたがシラバス＋テス友での学習ではもう少し学習時間は必要かもしれません。

今回の受験で体系的にテストについて学習できて非常に満足しています。ですがもっと早めに受けておけばよかったなと思いました...
いままで実務で得た知識しかなかったためスポーツで言う試合は沢山しているけど練習はほとんどしていない状態だったため業務を遂行できるようになるには手っ取り早いかもしれませんが大変かつ知識に偏りがある状態になっていたので気になっている人はとりあえず学習してみるとよいと思います。
#
今回は以上です。ご覧いただきありがとうございました！
階層構造をツリーに変換するコード

## 経緯
・以下のような階層構造ツリーを作りたい。

入力：
[0,1,2,2,2,3,2,2,3,2,3,4,4,5,5,4,4,5,4,4,1,1,1,2,1,1,1]



出力：
┬────
├┬───
│├───
│├───
│├┬──
││└──
│├───
│├┬──
││└──
│└┬──
│　└┬─
│　　├─
│　　├┬
│　　│├
│　　│└
│　　├─
│　　├┬
│　　│└
│　　├─
│　　└─
├────
├────
├┬───
│└───
├────
├────
└────


・階層構造ツリーを作成する関連で調べても、ディレクトリ風のテキストを作るものしか出てこない
⇒自分で作りました。


## 結論

とりあえずpythonで記載

```python:code1.py
def generate_tree(depths):
    """
    depths: list of non-negative整数。最初の要素は0で、それ以降に0は出てこないものとする。
    戻り値: 各行を表す罫線ツリーの文字列リスト。
    """
    # 入力チェック
    if len(depths) < 2:
        raise ValueError("入力は2行以上必要です")
    if depths[0] != 0 or any(d == 0 for d in depths[1:]):
        raise ValueError("1行目のみ0、それ以降に0は許されません")
    
    max_depth = max(depths)
    V, H, S = '│', '─', '　'   # 縦線, 横線, 全角スペース
    T, TEE, ELB = '┬', '├', '└'
    n = len(depths)
    lines = []
    
    for i, d in enumerate(depths):
        # 子ノード判定
        has_child = (i+1 < n and depths[i+1] > d)
        
        # 兄弟ノード判定
        has_sibling = False
        for j in range(i+1, n):
            if depths[j] < d:
                break
            if depths[j] == d:
                has_sibling = True
                break
        
        row = []
        for pos in range(max_depth):
            if pos < d-1:
                # ── 祖先レベルの縦線判定 ──
                # 後続行を順に見て、
                #   ・depths[j] < pos+1 → その祖先ブランチは終了 → 縦線なし
                #   ・depths[j] > pos → まだそのブランチに子孫あり → 縦線あり
                #   ・depths[j] == pos+1 → 同じレベルの子や孫 → 縦線あり
                # のいずれかで判定を打ち切る
                draw_v = False
                for j in range(i+1, n):
                    if depths[j] < pos+1:
                        # 祖先レベル pos はもう続かない
                        break
                    elif depths[j] == pos+1:
                        # depths[j] >= pos の間は縦線を引く
                        draw_v = True
                        break
                row.append(V if draw_v else S)

            elif pos == d-1:
                # 親からの分岐 ├ または └
                row.append(TEE if has_sibling else ELB)

            elif pos == d:
                # 自分自身の分岐 ┬（子あり）／─（子なし）
                row.append(T if has_child else H)

            else:
                # それ以降は横線で埋める
                row.append(H)
        
        lines.append(''.join(row))
    
    return lines


if __name__ == "__main__":
    # テスト用サンプル
    sample = [0,1,2,2,2,3,2,2,3,2,3,4,4,5,5,4,4,5,4,4,1,1,1,2,1,1,1]
    for line in generate_tree(sample):
        print(line)
```

関数として記載しています。
これを適宜、自分のツールに組み込みましょう
【C#・Unity】安全な変数宣言へ　getter / setterの使い方

# はじめに

C#で変数の値にアクセス・制御する方法として使われるのが `getter` / `setter`、つまり**プロパティ**です。

特に `public` で外部に公開する値は、そのまま変数として公開するのではなく、**適切に管理・保護する**プロパティを使います。


## 🔰 基本の書き方

```Player.cs
private int _health;

public int Health
{
    get { return _health; }
    set { _health = value; }
}
````

* `get` → 値を取り出す
* `set` → 値を設定する

使用例：

```Game.cs
player.Health = 100;
int hp = player.Health;
```

:::note
## アクセス修飾子の名前の付け方の慣習
C#ではアクセスレベルに応じた命名の慣習があります。

| アクセス修飾子 | 名前の付け方 | 使用例 |
| :-: | :-:| :-: |
| private フィールド |	camelCase（頭小文字）＋ 先頭に _ をつける |	_health, _score, _isAlive |
| public プロパティ |	PascalCase（頭大文字） |	Health, Score, IsAlive |
| 定数	 | ALL_CAPS(全て大文字) |	 PI, DEFAULT_SPEED |
| local 変数	 | camelCase（頭小文字）|	health, score, playerName |

:::

## ✅ 自動実装プロパティ（シンプル）

値の検証や制御が不要な場合は、以下のように短く書けます：

```csharp
public int Score { get; set; }
```

裏で自動的にフィールドが生成されるため、単純なデータ保持には非常に便利です。


## 🔒 読み取り専用プロパティ（getterのみ）

```cs
private int _maxHealth = 100;

public int MaxHealth
{
    get { return _maxHealth; }
}
```

または：

```cs
public int MaxHealth { get; } = 100;
```


## ✍️ 書き込み専用プロパティ（setterのみ）

```cs
private int _damage;

public int Damage
{
    set { _damage = value; }
}
```

読み取り不可のプロパティにすることもできますが、あまり多くは使われません。


## 🎯 バリデーション付きプロパティ

```csharp
private int _level;

public int Level
{
    get { return _level; }
    set
    {
        if (value >= 0)
        {
            _level = value;
        }
    }
}
```

`setter` で条件を付けることで、安全な値だけを受け付けることができます。
バリデーション以外でも値をセットする時に何かしら動作を付け加えたい時とかにも使えます。（フォーマット等）


## 🧪 private setter + public getter（外部から読み取りのみ可）

```csharp
public int Id { get; private set; }

public Player(int id)
{
    Id = id;
}
```

外部から値の変更はできず、初期化のみ許可したいときに便利なパターンです。


## 📦 static プロパティ

Unityなどで、ゲーム全体でスコアや設定値を共有したい場合、`static` を使って以下のように定義します：

```csharp
public static int GlobalScore { get; set; }
```

使い方：

```csharp
GameManager.GlobalScore += 10;
```
全シーン・全スクリプトで同じ値を使いまわせます。

## おわりに
C#のプロパティは、単なる値の取得・設定にとどまらず、安全性・可読性・拡張性を高める重要な機構です。

プロパティを正しく使い分けることで、クラス設計がぐっと洗練されます。
慣れないうちは命名規則とアクセス修飾子の組み合わせに気を配ることから始めてみましょう！
み
【Unity】ParticleSystemからいらないアセット参照を消すEditor拡張を作った

# はじめに
UnityのParticleSystemでは使用したい機能(モジュール)を追加をし、モジュールによってはMeshやTextureを設定して使用することができます。

しかし、一度モジュールにチェックをいれ、Meshを登録した後にモジュールのチェックを外すとMeshのアセット参照は残ったままになります。
そのためパーティクルをロードする際に不必要なアセットも巻き込んでロードされます。
これを防ぐために必要のないアセット参照は消すEditor拡張を作りました。

# ソースコード
https://github.com/ayaha401/ParticlePropertiesClear

# 仕組み
スクリプトで全プロパティをチェックして不要であれば消す…といった方法をできればよかったのですができなかったので各モジュールやEnumを設定した場合にアセットを設定できそうであればそれをif文でチェックしてNullを代入して消すといった方法で消してます。

## 1つのアセット参照を消す場合
例えばShapeモジュールの場合です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/608797/2dd58667-4bce-4c6c-8449-1efc9f967f7a.png)

ShapeがConeの時はTextureだけを入れることができます。
しかし、ShapeをMeshに変更すると

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/608797/625e2022-1130-4cfb-9433-7d79d517e3d7.png)

Meshの登録ができるようになります。

```C#
private void ClearShapeModuleProperties(ParticleSystem particleSystem)
{
    var shapeModule = particleSystem.shape;
    
    // shapeModuleが使用されていなかったら関係するアセット参照を消す
    if (!shapeModule.enabled)
    {
        shapeModule.texture = null;
        shapeModule.mesh = null;
        shapeModule.meshRenderer = null;
        shapeModule.skinnedMeshRenderer = null;
        shapeModule.sprite = null;
        shapeModule.spriteRenderer = null;
        return;
    }
    
    // 対応したMesh以外にアセット参照がある可能性があるので消す
    switch (shapeModule.shapeType)
    {
        case ParticleSystemShapeType.Mesh:
            shapeModule.meshRenderer = null;
            shapeModule.skinnedMeshRenderer = null;
            shapeModule.sprite = null;
            shapeModule.spriteRenderer = null;
            break;

        // 他にもパターンがあるが説明のために省略
        
        default:
            // どれにも一致しない場合はすべて除去
            shapeModule.mesh = null;
            shapeModule.meshRenderer = null;
            shapeModule.skinnedMeshRenderer = null;
            shapeModule.sprite = null;
            shapeModule.spriteRenderer = null;
            break;
    }
}
```

そのためこのようなコードを作成します。
まず、そもそもShapeモジュールを使用しないときは`if (!shapeModule.enabled)`の中ですべてのアセット参照にNullを入れます。
どんなアセット参照がこのモジュールにあるのかはモジュールのすべてのチェックマークやEnumをポチポチ切り替えて探します。

Shapeに設定されているモードがMeshの場合は`case ParticleSystemShapeType.Mesh:`でMesh以外のアセット参照を消します。
Coneなどを設定されている場合はMeshすらいらないので`default:`でMeshも含めて全部消します。

## Listを消す場合
CollisionモジュールなどではListを持っています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/608797/790515f3-6871-469e-b55b-4d55bf22bded.png)

この場合もモジュールを使わない場合やTypeがPlanesではない場合は参照を持つ必要がないので消します。

```C#
// 全てのPlaneを消す
void RemoveAllPlane()
{
    var planeCount = collisionModule.planeCount;
    if (planeCount > 0)
    {
        for (int i = planeCount - 1; i >= 0; i--)
        {
            collisionModule.RemovePlane(i);
        }
    }
}
```

このようなメソッドを作り、for文では要素を後ろから消します。
後ろから消している理由は普通に消すと`RemovePlane`ではそのIndexのPlaneが消え、以降のPlaneが詰められるせいで全部消せなかったりしたため後ろから消します。

また、

```C#
void ClearAllPlanes()
{
    for (int i = 0; i < 6; i++)
    {
        collisionModule.SetPlane(i, null);
    }
}
```
をこのようにNullを直接代入した場合はすべてNullになるため参照は消えますがListの大きさが確保されたままになってしまったのでやめまｓ
Obsidianインストールしてみた

# はじめに

きっかけは以下の投稿見て、ノートアプリのObsidianをまずは使い始めようと思って以下備忘録として残す。

https://x.com/ShinWorkout0207/status/1921149922025382152

# 内容

## インスートール

- 公式からダウンロードする
[Obsidian](https://obsidian.md/)

![スクリーンショット 2025-05-11 19.15.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/923146/c566b818-2780-41fe-b1bd-d2c5420d08a5.png)

- 日本語化

![スクリーンショット 2025-05-11 19.14.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/923146/0af3f1c9-bc18-45eb-80be-9678ef3dec89.png)

- クイックスタートをクリック
VSCodeに見た目似てる感じ。

![スクリーンショット 2025-05-11 19.24.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/923146/b15a6cbb-fd2b-499d-85de-eecf4b0994ac.png)


## テーマ設定

- 設定からテーマをインストールして適用(以下の記事参考)

[Obsidianのテーマを探した時のメモ](https://zenn.dev/hajimari/articles/i_obsidian_theme_exproler)

![スクリーンショット 2025-05-11 19.46.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/923146/5a906902-69d8-4771-bb2a-22c007ea6d2b.png)


## プラグイン

以下の記事参考に設定

- [がんばらないObsidianノート術](https://qiita.com/YUM_3/items/80cf5705a54f70ad7e5b#%E8%A8%AD%E5%AE%9A%E3%81%8B%E3%82%89%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E3%82%92%E7%B4%90%E4%BB%98%E3%81%91%E3%82%8B)

[Calendar](https://github.com/liamcain/obsidian-calendar-plugin)


>デイリーノートをカレンダー表示にしてくれるプラグイン。これあるだけでデイリーノートの使い方の幅が大きく広がります（過去参照がとても楽になるので）


[Obsidian-Thino](https://github.com/Quorafind/Obsidian-Thino)


>Obsidian上でTwitterのように「つぶやく」ことでメモが取れるツールです。詳しくはこの後説明をしますが、このMemosと普段のメモを使い分けることによって格段と「書く習慣」は身につきやすいと思っています。

とりあえずこんな感じの見た目で設定


![スクリーンショット 2025-05-11 20.06.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/923146/a8037e60-4e02-40d6-9b4d-af5f19f936ac.png)


# まとめ
notion使用していたけど使いやすそうなので試しに使ってみよう


# 続き
- [Obsidian 活用メモ](https://qiita.com/miya1221/items/9587f7681dba4085a495)

# 参考記事
- [Obsidian 日本語ヘルプ](https://publish.obsidian.md/help-ja/%E3%81%93%E3%81%93%E3%81%8B%E3%82%89%E3%81%AF%E3%81%98%E3%82%81%E3%82%8B)
- [ゼロイチObsidian｜ゼロからはじめるObsidian案内](https://qiita.com/hann-solo/items/22bcaa81b695ddb47238)
【因果推論】合流バイアスとはなにか


# 合流バイアスとは
合流バイアス（コライダーバイアス）とは、
複数の独立した原因変数A、Bが共通の結果変数C（合流点）に影響を与えるとき、
その結果Cでデータを絞り込んだり条件付けたりすると、
本来独立なはずのAとBの間に見かけ上の相関が生じる現象です。

# この記事の読者

* データ分析やマーケティング施策の効果検証を行う方
* 因果推論の基礎を学びたい研究者・学生
* モデル構築時の選択バイアスに注意したいエンジニア・アナリスト

# 具体的な例（小売業界）

* **要因A：プロモーション実施月**
  * セール月（12～3月）にDMやプッシュ通知で来店を促進
* **要因B：顧客の自発的購買意欲**

  * 本当に商品を必要として自ら来店する層
* **合流点C：購入した顧客**
  * プロモーションで来店 or 自発来店、いずれかで購入が成立
* **分析結果（フィルタ後）**

  * 「セール月に購入した顧客は離脱率が高い」と見えるが、
  * 実際はセール月は“意欲の低い層”を無理に取り込んでいるため
  * 自発層が多い非セール月と比べて離脱率が高くなるだけ

# DAGとは

因果関係を整理するための有向非巡回グラフ（Directed Acyclic Graph）。

* **ノード**：変数（原因・結果）
* **矢印**：因果の流れ
* **コライダー（合流点）**：矢印がぶつかる結果変数

# 今回の例で書いてみる

```
    プロモーション実施月 ──▶
                          ＼
                           購入した顧客（C）
                          ／
    自発的購買意欲      ──▶
```

* 矢印が交わる「購入した顧客」がコライダー
* ここで「購入顧客だけ」を分析対象にすると、
  プロモ月と購買意欲の間に偽の相関（負の相関）が生じる

# まとめ

* 合流点バイアスは「結果変数でデータを切る」ことで生じる偽の相関
* 分析モデルにコライダーを入れたり、そこによりデータを絞ったりしない
* 真の原因変数（A, B）を観測・モデル化し、因果構造（DAG）を意識することで回避
* あらゆる業界・領域で注意が必要な落とし穴です。
【Web Audio API】Microsoft SAM風の音声をブラウザで再現するツール「SAM TTS」を使ってみた

こんにちは。今回は、懐かしの **Microsoft SAM**（Windows XPでおなじみのロボット音声）をブラウザ上で再現できるツール「**SAM TTS**」を紹介します。

ただの紹介ではなく、実際にこのツールを使ってみた所感と、技術的にどうやって音声合成が実現されているのかを簡単に解説します。

![Screenshot 2025-04-26 at 5.32.08 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3959521/b33e24d7-9800-495f-a48f-400cf87847f2.png)

---

## 🗣 SAM TTSとは？

[**SAM TTS**](https://samtts.com/) は、ブラウザ上で動作する無料のテキスト読み上げツールです。Windows XP時代に存在した [Microsoft SAM](https://samtts.com/) の音声を、現代のJavaScriptと Web Audio API を使って再現しています。

特徴は以下の通りです：

- 完全無料＆ログイン不要
- 音声のピッチ、スピード、口の開き方（mouth）、喉の響き（throat）をカスタマイズ可能
- 複数のプリセット（Elf, Robot, Old Ladyなど）を選択可能
- 生成した音声を **WAV形式でダウンロード** 可能

---

## 🧪 実際に使ってみた
![Screenshot 2025-05-05 at 10.12.30 AM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3959521/7449cf08-d5c3-436e-b4d7-d2d72696fe79.png)

1. テキストを入力  
2. 声の設定を調整（例：ピッチを高くして「エルフ」風に）  
3. 「Speak」ボタンを押すと即再生  
4. 必要に応じてWAVファイルとして保存

動作も軽く、スマホからでも問題なく動きました。何より、「あの懐かしい声」が完全に再現されていて、思わず笑ってしまいました。

---

## 🔧 技術的な背景（簡単に）

SAM TTS は、ニューラルネットワークや音声モデル（例：Tacotron、VITS）を使っていません。  
代わりに、**Phoneme-based（音素ベース）の合成アルゴリズム**を用いています。これは、1980年代〜2000年代初期に使われていた方式です。

内部的には、文字列を独自の辞書で音素に変換し、Web Audio API で再生用の PCM バッファを生成しています。コード自体は JavaScript で完結しており、完全にクライアントサイドで動作するのが特徴です。

---

## 🕹 活用シーン

- レトロ風のゲーム開発でのナレーション
- YouTubeやTikTokでのナレーション音声
- 教育コンテンツやTTS技術のデモ
- 単純に「ネタ」として楽しむ😄

---

## 🌐 サイトはこちら

興味のある方はぜひ触ってみてください。  
→ [https://samtts.com/](https://samtts.com/)

---

## 📝 まとめ

SAM TTS は、単なるノスタルジーにとどまらず、創作活動にも使える軽量かつ自由度の高いTTSツールです。AIモデルでは再現しにくい独特な「キャラのある声」を、現代のブラウザ技術で蘇らせてくれます。

TTSやWeb Audioに興味のある方、懐かしい音声をもう一度聞いてみたい方にはおすすめのツールです！

## 🔗 参考リンク

- [SAM TTS: Bring Back the Classic Microsoft SAM Voice in Your Browser (Medium)](https://medium.com/@indiehackercool/sam-tts-bring-back-the-classic-microsoft-sam-voice-in-your-browser-72046296ea4a)  
- [SAM TTS 紹介ノート (HackMD)](https://hackmd.io/7xzc9yD5TnCAc7vH9dOiwg)
ネットワーク完成？内部用VMと外部用VMの作成とテスト

前

https://qiita.com/shimeji_k/items/f373baa926ac904b681f

まずやること
=======
ネットワーク環境がある程度整ったので
内部向けネットワークと外部向けネットワークを作ってみる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4067323/1769be78-85a2-4dd5-82b7-891ca2cf76fc.png)

| 用途           | ネットワーク帯域          | 備考                |
| ------------ | ----------------- | ----------------- |
| 管理ネットワーク     | `192.168.14.0/24` | Proxmox Web/SSH/VMなど |
| Proxmoxクラスタ専用    | `192.168.15.0/24` | Proxmox クラスタ専用 |
| Ceph Public     | `192.168.20.0/24` | Ceph Public     |
| Ceph Cluster     | `192.168.30.0/24` | Ceph Cluster    |
| iLO/IPMI     | `192.168.50.0/24` | BMC管理インターフェース     |
| 外部公開向け     | `172.16.0.0/16` | RTX3500経由で外と通信用（ゲームサーバ公開など） |

## VM（内部/外部）
### 内部VM
Gitbucket（構築エビデンスやら証跡のこし、課題管理）
mariaDB(gitbucket/Zabbix用)

### 外部VM
Rustゲームサーバー
* ただし正式かどうじゃないのでRTX3500にNAT設定していない

を建てて問題なく稼働しているのを確認

ちゃんとそれぞれの通信が確立しているのも確認できた！やった！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4067323/c75a1386-eac5-469b-a95e-4e39279bf8e5.png)
圧倒的メモリ不足///

NetDataで視覚的に見ることができるようにしたもの成長
知らなかった便利なミドルウェア多くなりましたね

なお、足りない部材（LCケーブルとかは）Alliexpressで買ったりしてるけど全然届かなくてやきもき

Cephのクラスタぶっ壊したり復旧させたりテストしてみた結果
エラー消えない
mgrがException吐いて再起動したログが残ってしまった
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4067323/a07e335f-2868-4f72-b6f4-65f8ae9b05ac.png)

しかもノード（Mon）が偶数というw
まだ、設定していないサーバーが残っていますから！（全部導入すると偶数になってしまう）
別途Mon稼働をさせる適当な端末を探さないといけないですね

そして、Rustのゲームサーバーを起動
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4067323/135b0650-9082-449e-b9e9-eed3a3b2051b.png)

共用していたネットワークを極力排除したおかげ？もあり
今のところサクサク動作しております。
ライブマイグレーションも正常に動作します！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4067323/5da6b4af-aab6-463d-beb0-cf54498fa86d.png)


## ここまでやって思ったこと
コンソールのコマンドが違いすぎて
YAMAHA・アライドテレシス・DELL OS9
やってる最中たまに混乱いたしますね
（コマンドは筋トレ）


次はデバイス届いたらサーバーセットアップ
全然揃わないｎ

次回はあるのか？

https://qiita.com/shimeji_k/items/3a60b3f397e3f65ce914
【TypeScript】TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" forエラーが発生する

# はじめに
tsファイルをコマンドで叩いて実行する際に、表題のエラーになりました。
解決に時間がかかってしまったため、備忘録としてまとめます。

# 問題
`npx ts-node --esm ./batch/index.ts `コマンドを実行すると`TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" for`が発生する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3993509/2ddbb307-c221-444a-9674-6ba7f82e6737.png)

#### コマンドの意味を理解

* **npx**：Node.jsのパッケージをインストールすることなく実行できる
* **ts-node --esm**：`ts-node`はTypeScriptファイルを直接実行できるツール（JavaScriptに変換してくれる）、`--esm`は「ESモジュールモードで実行してください」を指定
* **./batch/index.ts**：実行するファイルパス

# 原因
Node.jsはjavascriptを実行するプログラム、Node.jsは「.ts」がなんのファイルか認識できていなかったことが原因でした。

**`ts-node --esm`でJavaScriptに変換して実行してくれるのでは？となりました。**

* `--esm`で指定したESモジュールモードは、拡張子の扱いが厳格だそうです。
特に、import文など（`import {} from './module.js'`）では必ず拡張子の指定が必要になります。（CommonJSモードは`require('./module')`のように拡張子を省略できる）

* ts-nodeはコンパイル時に.tsを`.js`に変換しますが、コード内のインポート文の拡張子は自動的に修正しません

ファイル内で、import文を使用している場合、Node.jsはimport内の「.ts」を認識できず、エラーとなります

# 解決方法
`npx tsx ./batch/index.ts`で実行する

`tsx`はTypeScriptをJavaScriptに自動的に変換してくれます。
また、`ts-node --esm`では解決できないインポート文の拡張子問題なども自動的に解決してくれます。

:::note warn
**ファイル拡張子の「.tsx」とは違う**
今回使用したのはコマンドラインツールの「tsx」
JSX記法のTypeScriptバージョンの拡張子「.tsx」と全く同じ名前ですが異なります
:::


# おわりに
コマンドのtsxとJSX記法のtsxは違うよね？あっているよね？ってなりました。

# 参考
https://tsx.is/

https://www.npmjs.com/package/ts-node

https://typestrong.org/ts-node/
APIを使ったウェブアプリを３時間で作った話｜ハッカソンに参加して感じた成長

# はじめに
こんにちは、Reactを勉強中の私がハッカソンに参加してきた記録を、ゆるっとまとめました。技術的な話より「どんなふうに進めたか」「どんな学びがあったか」をメインに書いています。

### 開催のレポートはこちら

https://qiita.com/kitao6/items/4d4437c83b9e6ec19716

# APIを使ってアプリを作ろう！
今回のハッカソンのテーマは「API」を使うこと。
全体で４〜６人くらいのチームが６チームくらいありました。
実はハッカソンに参加するのは２回目で、２ヶ月前に初めて参加しました。その時のテーマは「AIを使うこと」。

https://qiita.com/kitao6/items/8f5eac0c31466c4ffbd7

今回はAPIということで、また新しいチャレンジです。
普段の開発でもまだAPIを使ったことが無いので、少しドキドキでした。


## API で 何する？ 何使う？
APIで何かサービスを作ろう、考えた時に、まずはどんなAPIがあって、何ができるのかを調べるところからスタート。
天気予報やニュース、ポケモンAPIなど色々あって、チームで話し合って何を作るか考えました。

## お散歩日和チェッカー
天気のAPI「OpenWeatherMap API」と犬の画像をランダムに表示する「DOG API」を組み合わせて「今日、犬の散歩に行けるか？」を天気でチェックするアプリを作ることに。

名前は「お散歩日和チェッカー」。
天気の情報と可愛い犬の画像を使って、お散歩日和かどうかを表示します。
早速デザインにしてくれるメンバーがいて、完成のイメージをみんなで共有することができました

![スクリーンショット 2025-05-11 15.48.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3927903/f0cb62d4-d6b1-4c53-8845-7804eda8c6ec.png)

### DOG API より unsplush がいいかも
犬画像は最初 DOG API を使ってみたけど、ちょっと好みじゃない画像が多くて、最終的にはUnsplashで「dog」検索して画像を表示することにしました。

# 技術スタック
技術スタックはReact + Vite + JavaScriptで、みんなReactを学習中の段階。なので環境構築がわりと大変でした。GitHubでやる？Live Share？みたいなところで少し迷走。リポジトリもうまく作れなかったりして、かなり時間を使いました。
コードを共有するときも、コンフリクトしたりとても大変だった〜！
一人では問題なく進むところも、チームではまた環境が違うので、慣れた人がいないとなかなか大変でした。

## チームで役割分担
お天気API、犬のAPI、UI担当とそれぞれ役割分担をして進めました。
限られた時間（３時間）しか無いから、ここの分担がかなり重要で、チームとして協力できるかどうかがすごく重要になってくる。
困ったら「ちょっと今いい？」って声を掛け合って、一人で解決できないエラーはみんなで集まって解消して進めました。声かけ大事！

# アプリ完成、発表
完成させたアプリを発表するまでがハッカソンのイベント。
同じ「APIを使う」というテーマでも各チームが作るアプリは様々で、苦労したところや良かったことを参加者全員で共有しました。みんなのアイディアでできたものを見てとても楽しい時間です！（発表は苦手だけど）

## 自分の成長を実感
今回参加して良かったと思ったことは、前回よりも自分n「成長」を感じられたこと。
前回（２ヶ月前）は、経験者の人に正直引っ張ってもらってるだけだなーって思ったけど、今回は自分からアイデア出したり、困ったら相談できたり、エラーの内容を考えたり、前回よりもできること増えたかも！って実感しました。

チーム全体もちゃんと話し合って、協力して、最後までアプリを完成させられたのがすごく嬉しかった！

# ハッカソン参加して良かった！
始まる前はできるかな？っていう不安があるけど、一人じゃ無いから、なんとかなる！めちゃくちゃ濃い時間になりました。
何より「一人で開発してるだけじゃ味わえない達成感」がある。
短時間でモノを作り上げるって、楽しいだけじゃなくて、めちゃくちゃ学びにもなります。

# おわりに
もし「ハッカソン気になるけど、自分のスキルで大丈夫かな…」って思ってる人がいたら、とりあえず出てみるの、ほんとにおすすめです！Reactを勉強中の私でも、周りと協力してなんとかアプリを完成させられたし、「前より成長してる！」って自分に気づけるだけでも、すごく大きな経験になります。

読んでくれてありがとうございました！
次のハッカソンも、たぶん出ます🐕

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

https://projisou.jp
【データ分析の罠】シンプソンのパラドックスとは

# はじめに
こんにちは、データ分析に興味があるみなさん！
今回は、分析に潜む意外な落とし穴「**シンプソンのパラドックス**」について紹介します。
シンプルに見えるデータでも、実は危険な罠が潜んでいるかも…？

# この記事の対象者

- 因果推論やデータ分析に興味がある方
- データ分析初心者で注意点を知りたい方
- 数字を見て意思決定をする機会が多いビジネスパーソン

# シンプソンのパラドックスとは

**シンプソンのパラドックス（Simpson’s Paradox）とは、
個々のグループでは明確な傾向があるのに、それらをひとまとめにすると逆の結果が出てしまう**統計的現象です。

例えば、「Aのほうが良い！」と各店舗では言えるのに、
全体を集計すると「Bのほうが良い！」と逆転することが起きるのです。

一体どういうこと？実際の例で見ていきましょう。

---

# 小売業界での具体例

架空の小売店『スーパーABC』の広告戦略を例にします。

スーパーABCは2つの店舗を持ち、それぞれ違う広告戦略を試しました。

| 店舗 | 広告戦略 | 売上前年比 |
| --- | --- | --- |
| 店舗A | オンライン広告 | **+20%** |
| 店舗B | チラシ広告 | **+10%** |

これを見ると、店舗ごとでは明らかにオンライン広告の方が効果的ですよね。
でも、これを会社全体としてまとめてみると、なぜか違う結果に…。

| 広告戦略 | 全体の売上前年比 |
| --- | --- |
| オンライン広告 | **+5%** |
| チラシ広告 | **+8%** |

なんと、全体ではチラシ広告の方が良い結果になってしまいました。

なぜでしょう？

これは、店舗の規模が大きく違っていたからです。
- 店舗A（オンライン広告）はもともと規模が小さく、前年比+20%でも全体への貢献は小さい。
- 店舗B（チラシ広告）は規模が大きいため、前年比+10%でも全体の売上に与える影響が大きかった。

つまり、「店舗の規模」という隠れた要素を無視して単純にまとめてしまうと、
誤った結論を出してしまうことがあるのです。

これが**シンプソンのパラドックス**です。

# この事例から学ぶ分析するときの注意点

### ① 単純な「平均」や「合計」だけで判断しない！

データの集計方法を変えるだけで結果が逆転することがあります。
背景まで含めて分析することが大切です。

### ② 「隠れた要因」（交絡要因）に気をつける！

今回では「店舗規模」が隠れた要因でした。
データに隠れた別の影響要因を常に意識しましょう。

### ③ 全体だけでなく個別グループでも検証する！

データを異なる切り口で見ることで、パラドックスを回避できます。
分析では複数の視点が重要です。

# まとめ

シンプソンのパラドックスはデータ分析に潜む意外な罠ですが、
これを知ることでデータを見る目が鍛えられます。
ぜひ、日常のデータ分析や意思決定で意識してみてくださいね！
Watson AssistantでDynamic Optionsを使う方法

以下のようなデータをカスタムエクステンションを作ってAPI連携し、
idを使ってDynamic Optionsを生成したい場合
```
data ={
  "title": "hoge",
  "detailinfo": [
    {
      "id": 1,
      "content": "fuga"
    },
    {
      "id": 2,
      "content": "piyo"
    }
  ]
}
```

以下画像のように設定すればDynamicにOptionが生成される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3641091/f868099e-a85d-4c41-9f4f-080b3c77d12b.png)

$item.id
としてあげるのがポイント。


また、選択した結果のcontentを表示したい場合は適当に変数を作成した後、
ActionのStep Variableを選択 + .item.content
とやってあげると、contentの内容も取得できる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3641091/562cdae1-35ef-46f9-b717-8840cee995b3.png)
f-string vs format vs %：Python の文字列フォーマット比較

Pythonで文字列を構築する場面は日常的に訪れます。その際に登場するのが、文字列フォーマットの3つの代表的な方法：

* `%` 演算子による古典的なフォーマット
* `str.format()` による柔軟なメソッド形式
* `f-string`（フォーマット済み文字列リテラル）による最新のシンタックス（Python 3.6以降）

それぞれに一長一短があり、どれを使うべきか迷う場面もあるでしょう。


## 各フォーマット方法の基本構文

### 1. `%` 演算子

C言語由来の伝統的なスタイルです。

```python
name = "Alice"
age = 30
print("My name is %s and I am %d years old." % (name, age))
```

* **メリット**：短く書ける、Python 2 でも使用可能
* **デメリット**：型指定（%s, %dなど）ミスがエラーに繋がりやすい


### 2. `str.format()` メソッド

Python 2.7 / 3.x 以降でサポートされている汎用的な方法です。

```python
print("My name is {} and I am {} years old.".format(name, age))
```

* **メリット**：名前付き引数や順番の制御が可能
* **デメリット**：やや冗長で長くなりがち

```python
print("My name is {name} and I am {age} years old.".format(name="Alice", age=30))
```


### 3. f-string（Python 3.6+）

もっともモダンで人気の高い方法です。

```python
print(f"My name is {name} and I am {age} years old.")
```

* **メリット**：簡潔で直感的、式評価も可能
* **デメリット**：Python 3.6 以上でのみ使用可能


## 使いやすさの比較

### 1. 直感性と可読性

* `f-string` は **変数や式がそのまま書ける** ため、コードの可読性が高いです。
* `format()` は **柔軟性はあるが、記述が冗長になりやすい**。
* `%` は **シンプルだが、読みづらくバグの温床にもなりやすい**。

### 2. 複雑な構造に対応できるか

たとえば辞書や計算式を埋め込みたい場合：

```python
user = {"name": "Alice", "age": 30}
print(f"My name is {user['name']} and I will be {user['age'] + 1} next year.")
```

このような **式埋め込み**ができるのはf-stringだけの特権です。


## パフォーマンス比較

Python の `timeit` モジュールで実行速度を比較してみましょう。

### 1. ベンチマークコード

```python
import timeit

name = "Alice"
age = 30

print("f-string:", timeit.timeit("f'My name is {name} and I am {age}.'", globals=globals()))
print("format():", timeit.timeit("'My name is {} and I am {}.'.format(name, age)", globals=globals()))
print("% operator:", timeit.timeit("'My name is %s and I am %d.' % (name, age)", globals=globals()))
```

### 2. 実行結果（例）

| 方法       | 実行時間（秒、10万回実行） |
| -------- | -------------- |
| f-string | 0.12           |
| format() | 0.19           |
| % 演算子    | 0.17           |

### 3. 考察

* **f-string が最速**
* `format()` は一番遅い
* `%` は中間程度

Python公式ドキュメントでも、**f-string はパフォーマンス的にも推奨**されています。

## 実用面での使い分け

### 1. Python バージョンによる制限

* **Python 3.5 以下**：f-string 非対応 → `format()` を使う
* **Python 3.6 以上**：f-string を推奨

### 2. チームやプロジェクトのルールに注意

* 混在するとレビューや保守が難しくなる
* チームで **書式統一のコーディング規約**を決めておくのがベスト
[Visual Studio Code ポータブルモード] 異なるバージョンのVS Codeを開発PCに保持する方法

# [Visual Studio Code ポータブルモード] 異なるバージョンのVS Codeを開発PCに保持する方法

AIサーポートを受けた開発、AI Driven Development、セキュリティ、開発効率など様々な点から最新版のVS Codeで開発を行うことは当然ですが、古い環境でしかサポートされていない機能があったりします。

VS Code (version 1.100 )の ExtensionのRemote SSH(ver 0.120.0)でAmazon linux 2につなげないという問題があり、解決として古いバージョンで繋ぐことにしましたが、古いままだと他の開発に影響するため、最新のVS CodeをメインをPCにインストールして使用する。古いバージョンは配布されたアプリケーションをそのまま使用し、別で保持するという方法を取ることにしました。

なお、２０２５年５月１１月現在でAmazon linux 2につなげて正常にgitを動作させるために、VS Code (Version: 1.85.2 )を使っています。

## 方法

### VS codeのサイトから使用したいアプリケーションをダウンロードする。

[VS codeのサイト](https://code.visualstudio.com/updates/v1_85)にアクセスし、ダウンロードを行う。

### 圧縮されたファイルを解凍する。

### 解凍されたファイルを使用したいフォルダに移動させる。

解凍したVS Codeを使うと、設定やextensionのファイルが、同フォルダのcode-portable-dataに出力されます。管理しづらいところに置かない。



これだけで基本的に使用ができるようになります。ただ、VS Codeを使うときにcode-portable-dataフォルダへの書き込みの権限がないことでエラーが出ることがあるようなので注意すること。（当然ですが）



インストールしたVS Codeとは異なるフォルダにextensionが入っているため、必要なものは再度extensionをインストールする。



以上
現場のノウハウを蓄積するAIナレッジアプリを開発してみた

# はじめに
趣味でプログラミングを勉強しながらアプリ開発にも挑戦しているので、私が開発したアプリや今挑戦しようとしていることを文章で残していけたらと思いQiitaを登録しました。私の開発ログとして情報発信していきますので、少しでも皆様の役に立つ情報になれば嬉しいです。(プログラムスキルはまだまだ低いので、アプリ開発を通して勉強している状況です)

今回は、製造業の工場現場で生み出されるノウハウを蓄積するアプリを開発したので、紹介します。

# 今回のアプリを作成するきっかけ
私は製造業の生産技術者として長年仕事をしています。そこで、「製造業って全然DX化が進んでないじゃん」って毎回感じます。製造現場では、日々のトラブル対応などが保全記録として残されていきますが、その多くが活用されないまま埋もれてしまっています。また、何もログが残っていない場合もあります。

何かトラブルが発生すると、
「あの時、似たような問題があった気がするけど、どこに書いてあったかな……」
「この問題、あの人に聞かないと分からないな」
とかなり属人化してたり、情報の検索性が悪かったりと、製造業はデジタル化が全くされていないです。

誰が情報をもっているか探し回ったり、保存されている情報を探し回ったりと無駄な事に時間を費やしてしまっているのです。
現場のPDCAを高速で回すには「**情報の検索性**」を上げる必要があるなと思いました。

そこで、自然言語で保存したトラブル対応内容をAIを活用して自然言語で検索・再活用できるアプリをPythonで開発したのでご紹介します。まだ開発初期段階のため機能としては少ないですが、皆様の発想のヒントになれば幸いです。

# 構成と使用技術
構成は以下になります。
今回は、自然言語で登録した保全記録をSentenceTransformerのAIモデルを利用し、文章をベクトル化しました。
また、FAISSを利用し、類似文章のベクトル検索を行うことで、自然言語による保全記録検索を可能にしました。

| 機能 | 使用技術 | 用途|
|-----------:|----------------:|----------:|
| ベクトル検索      | FAISS        |類似文章を検索|
| テキストベクトル化     | SentenceTransformer|自然言語をベクトルに変換|
| GUI       | PyQt6        |UI作成用|
| データベース        | SQLite3|ノウハウを保存|

# 実現したいこと
- トラブル対応内容を自然言語で検索できる
- 過去の類似事例をベースに、問題の再発防止や処置方針のヒントを得られる
- オフラインで完結できるシンプルな仕組み

# 画面構成
## 1.検索画面
設備を選択し、「問題」を自然言語で入力することで、「問題」に類似した保全記録が表示されるようにしています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4083869/e69df232-7392-44d6-ba3b-74115673ab85.png)

## 2.保全記録追加画面
設備を選択し、「問題」「原因」「対策」「担当者」を入力できるようにしています。必要に応じて、ファイルも添付できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4083869/ed9e6ca1-077e-4d21-9b5e-7619309ab872.png)

## 3.保全記録一覧表示画面
登録した保全記録を一覧で表示します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4083869/80ae726c-2d2d-4c5e-bbf3-8d73a08aeaa4.png)

## 4.設備マスタ管理画面
「設備」はドロップダウンリストで選べるようにしているため、選択できる設備名を登録する画面です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4083869/83615b76-9973-4e36-98fa-1620b0f73c94.png)

# 工夫した点

## ベクトル検索の工夫
自然言語でのデータベースからの検索性を向上させるために、「設備」「問題」の形式に明示的に分け、2段階でデータベース検索を行いました。
- ステップ1：「設備」でデータベースから検索
　→設備名は登録しているリストから選ぶ形式にすることで、表記ゆれをなくした
- ステップ2：設備名で絞ったデータから「問題」で類似項目を検索

## AIモデルをconfig.jsonとして外出し
このアプリでは、類似検索にSentenceTransformerのAIモデルを利用しています。AIモデルを柔軟に切り替えられるようにconfig.jsonとして外部化し、プログラム側ではこれを読むようにしました。

```json:config.json
{
  "search_model": "multi-qa-mpnet-base-dot-v1",
  "cluster_model": "all-mpnet-base-v2"
}
```

# 今後やりたいこと
- 問題内容のクラスタリングによりカテゴリごとでの問題解析を可能にする
- PowerBIなどBIツールなどの連携をしやすくする
- Web化によりどこからでもアクセス可能にする

# 最後に
最後まで読んで頂きありがとうございます。
今後も「こういうアプリあったらいいな」と思うものを開発しながら情報発信できたらと思います。
皆様の反応が、継続していこうというモチベーションに繋がりますので、コメントなどいただけたら嬉しいです。
Windows環境のpsqlにパスワード入力無しで入る

DBに対しpsqlコマンドなどで処理を投げたい時がある。
このとき処理を書いたシェルスクリプト等を実行するとパスワード入力を求められて自動化に失敗する。
これが鬱陶しいのでパスワード入力を省略する。
たまにやろうとすると忘れているのでメモ

# 環境
- Windows11
- PostgreSQL15

# パスワードファイル作成
psql接続設定を記述したファイルを作成する。
```pgpass.conf
hostname:port:database:username:password
```

上記ファイルを`C:\Users\username\AppData\Roaming\postgresql\`に配置する。



# 参考
https://www.postgresql.jp/document/15/html/libpq-pgpass.html
「一歩ずつマスターする論理学入門」第一章

# 「一歩ずつマスターする論理学入門」第一章のまとめ

> **注意：この記事は学習途中の内容をまとめたものであり、誤りを含む可能性があります。**
> 
> 間違いがあれば、ぜひご指摘いただけると幸いです！

論理学を学び始めて、自分なりに感じた点を整理するためにこの記事を書いています。  
内容としては、「一歩ずつマスターする論理学入門」を参考にします。また、この本は論理学という対象を扱っていますが、読者対象として哲学を学ぶ人を想定しています。異なる分野での学習を考えていた方は得られるものが少ないかもしれません。

ですが、同じように論理学を学ぶ方のヒントになったり、「これはちょっと違うかも！」とコメントをいただける場になれば嬉しいです。

## 目次

- [はじめに](#はじめに)
- [推論とは何か？](#推論とは何か)
- [命題とは？](#命題とは)
- [推論の妥当性と命題の真偽](#推論の妥当性と命題の真偽)
- [オイラー図による推論の視覚化](#オイラー図による推論の視覚化)
- [命題論理と述語論理](#命題論理と述語論理)
- [矛盾と整合性](#矛盾と整合性)
- [演繹的推論と帰納的推論](#演繹的推論と帰納的推論)
- [おわりに](#おわりに)

## はじめに
論理学の対象は推論や論証とよばれるもの。このことから説明をはじめます。

## 推論とは何か？

論理学では、ある主張（結論）を導くための根拠となる主張（前提）との関係を「推論」と呼びます。

**例**

- 前提：すべての人間は死すべき存在である。
- 前提：ソクラテスは人間である。
- 結論：ソクラテスは死すべき存在である。
これらの関係を**推論**と呼びます、
## 命題とは？

命題とは、**真**または**偽**を問うことができる文のことです。

**命題の例**

- 「今日は雨が降っている。」
- 「2は偶数である。」

**命題でない例**

- 「こんにちは！」（挨拶）
- 「ドアを閉めてください。」（命令）
- 「明日は晴れますか？？」（疑問）

## 推論の妥当性と命題の真偽

推論を評価するには、以下の2点を考慮します。

- 命題それぞれの「真偽」
- 推論自体の「妥当性」

**妥当な推論**：前提がすべて真 → 結論も必ず真  
**妥当でない推論**：前提がすべて真 → 結論が真とは**限らない。**

## オイラー図による推論の視覚化

視覚的に推論の妥当性を確かめたいとき、[オイラー図](https://ja.wikipedia.org/wiki/%E3%82%AA%E3%82%A4%E3%83%A9%E3%83%BC%E5%9B%B3)が有効なことがある。ベン図と違って網羅性を変えやすいので、推論で注目したい部分の視覚化に便利(？)



## 命題論理と述語論理

| 論理の種類 | 特徴 |
|------------|------|
| 命題論理 | 命題を基本単位とし、否定・含意・連言・選言を扱う |
| 述語論理 | 名前・述語・量化子（全称 ∀、存在 ∃）|

**述語論理は命題論理を拡張したもの**と捉えるとよいと思います。

## 矛盾と整合性

- **矛盾**：命題の集まりが同時にすべて真になる状況が存在しない
- **整合性**：命題の集まりがすべて真になる状況が少なくとも1つは存在する

## 演繹的推論と帰納的推論

- **演繹的推論**：前提が真 → 結論も必ず真
- **帰納的推論**：前提が結論を支持するが、必ずしも結論が真になるとは限らない

## おわりに

今回は「一歩ずつマスターする論理学入門」の第1章をまとめました。最終的には述語論理の証明論の基礎までゆっくり気長にですが、掘り下げていきたいと思います。次は第2章を中心に扱う予定です！ご指摘・コメントをいただけると学びになります！
[LinuxでLINEを使う]chrome/edgeのを利用する方法

## 📝 前書き

2025年になっても、**LINEの公式Linux版は未だにリリースされていません**（怠惰すぎる…）。  
もちろん `wine` を使ってインストールすることも可能ですが、**できるだけシンプルに使いたい**ので、以下のQiita記事の方法を参考にしました：  
👉 [https://qiita.com/north_redwing/items/357bf0cfbc17990a5276](https://qiita.com/north_redwing/items/357bf0cfbc17990a5276)  

LINEは仕事でしか使わないため、どうせブラウザは開くし、**ブラウザベースで十分**だと判断しました。

---

## ❗ 問題点

Qiita記事内の「**LINEのショートカットを作成**」ステップは、  
**最新版のChrome/Edgeではそのまま使えなくなっています。**

- `chrome-extension://LINEのID/index.html` をアプリとしてインストールすることも**できません**。

---

## 🔧 解決の仕組み

Chrome（またはEdge）は `--app="リンク"` の形式で**ウェブページをアプリ風に起動**できます。  
この仕組みを利用して、以下のように起動すればOKです：
```
    chrome --app="chrome-extension://LINEのID/index.html#/"
```
この方法は **Chrome/Edgeの両方で有効**です。

---

## ✅ 手順まとめ

以下は、前述のQiitaの記事とほぼ同じですが、**LINEアイコンを簡単に取得する方法**を含めた改良版です。

1. LINE拡張機能をインストールし、**開発者モードでIDを確認**する  
2. 以下のリンクを準備する：chrome-extension://LINEのID/index.html#/
3. [LINE公式サイト](https://line.me/) を開いて、**アプリとしてインストール**する（これでLINEアイコンが手に入る）  
4. `~/.local/share/applications` にある `.desktop` ファイルを編集：
- `Exec=/opt/...`の--app部分を以下のように変更：  
```
    --app=chrome-extension://LINEのID/index.html#/
```
最後、**デスクトップをリロード**（またはPCを再起動）

---

## 🎉 完成！

これで、**ブラウザベースの完璧なLINEアプリ**がLinux上で使えるようになります！
Reactでコンソール画面に二重に表示されてしまう

# はじめに
propsやstateの更新が無いはずなのに、コンソール表示が思っている数の2倍表示されてしまうので、なぜ？と思い調べた結果をまとめます。

# 問題
デバッグ用にconsole出力をしていたのですが、暗めの似たようなコンソール表示が二重に出てしまうエラーが起きました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2779353/4bb9a7c2-a3c6-44c3-ab0a-925e20dd9cfb.png)

コンソールが表示される回数は、レンダリングされた回数になります。
stateの更新や親からのpropsの受け渡しで子のpropsが更新された場合などにレンダリングが再度走るはずですが、4回も更新した覚えはありません、、

# 解決方法
main.tsx内にある ```<StrictMode>```タグ というのが原因でした。
```main.tsx
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { ToDoApp } from "./ToDoApp";
import { ChakraProvider } from "@chakra-ui/react";

createRoot(document.getElementById("root")!).render(
  <StrictMode> // こいつが原因
  <ChakraProvider>
    <ToDoApp />
  </ChakraProvider>
  </StrictMode>,
);

```
```<StrictMode>```タグとは開発時のみに有効になるもので、本番環境では動作せず潜在的なバグを早期に発見するための開発ツールです。

そしてStrict Mode では、以下のような開発時専用の挙動が有効になります。
- #### レンダーを追加で 1 回行います
- #### エフェクトの実行を追加で 1 回行います
- #### ref コールバックの実行を追加で 1 回行います
- #### コンポーネントが非推奨の API を使用していないかチェックします

つまり、今回の場合は「レンダーが追加で1回行われていた」ということですね。
```<StrictMode>```タグをコメントアウトすると

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2779353/0265db3c-2abd-4f97-b710-f6a23421703d.png)
二重表示が無くなりました！

# おわりに
慣れるまでは、気にせずStrictModeを有効にする方が良さそうですね。

# 参考
https://qiita.com/Sicut_study/items/3247f55e8ae7992485e1

https://ja.react.dev/reference/react/StrictMode#enabling-strict-mode-for-entire-app