OmniAICreator/Qiita-1.07M huggingface dataset:
cscの作法 その536

# 概要
cscの作法、調べてみた。
練習問題やってみた。

# 練習問題
wpfを1ファイルで書け。

# 方針
- xamlを使わない。
- Windowクラスを使う。

# 参考にしたページ

https://qiita.com/Stosstruppe/items/c92d066754ef8c21177d


# サンプルコード

```

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Threading;

namespace Wpf
{
	public partial class MainWindow: Window {
		public MainWindow() {
			var clock = new TextBlock();
			clock.FontSize = 30;
			var timer = new DispatcherTimer();
			timer.Tick += (sender, e) => {
				var dt = DateTime.Now;
				clock.Text = dt.ToString();
			};
			timer.Interval = TimeSpan.FromSeconds(1);
			timer.Start();
			Title = "Clock";
			Width = 320;
			Height = 100;
			Content = clock;
		}
	}
	class MainApp {
		[STAThread]
		public static void Main() {
			MainWindow mwnd = new MainWindow();
			Application app = new Application();
			app.Run(mwnd);
		}
	}
}




```

# 実行結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/8a163984-f4a0-bd90-f82a-5deddc4c5a90.png)



以上。
M5NanoC6、8x8 Puzzle Unit  (Unit Puzzle ?)で遊ぶ。


x 過去ログを見よ!!!


![o_coq646.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/1ab29420-99cf-c4e9-d4d6-97188db10439.jpeg)



```c++


//WS2812E_8x8_VRAM_M5NanoC6_1


//インクルド
#include <Arduino.h>
#include <Adafruit_NeoPixel.h>


//定義
#define NUM_LEDS 64
Adafruit_NeoPixel strip(NUM_LEDS, 2, NEO_GRB + NEO_KHZ800);


void setup() {

  //RGB LED
  pinMode(2, OUTPUT);
  digitalWrite(2, HIGH);

  //RGB LED setup
  strip.begin();
  strip.show();

  //USBシリアル用の接続ウェート
  Serial.begin(115200);
  for (int i = 0; i < 9; i++) {
    Serial.print(".");
    delay(500);//接続待ち
  }//for
  Serial.println();

}//setup


int OnOff = (~0);
int line = 7;
int column = 7;

unsigned char Pixel[8][8][3] = {
  { {5,5,5},{5,5,5},{5,5,5},{5,5,5},{5,5,5},{5,5,5},{5,5,5},{5,5,5} },
  { {5,5,5},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{5,5,5} },
  { {5,5,5},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{5,5,5} },
  { {5,5,5},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{5,5,5} },

  { {5,5,5},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{5,5,5} },
  { {5,5,5},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{5,5,5} },
  { {5,5,5},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{5,5,5} },
  { {5,5,5},{5,5,5},{5,5,5},{5,5,5},{5,5,5},{5,5,5},{5,5,5},{5,5,5} }
};


void loop() {

  //on-off
  if (OnOff != 0) {
    int k = 0;
    for (int i = 0; i < (line + 1); i++) {
      for (int j = 0; j < (column + 1); j++) {
        strip.setPixelColor(k++, strip.Color(
          Pixel[i][j][0], Pixel[i][j][1], Pixel[i][j][2]));
      }//for j
    }//for i
  }//on-off

  strip.show(); //リフレッシュ

  delay(300);//ダミー

}//loop



```
SQLパズル 55 競走馬の入賞回数   解法2 メモ

# 概要
SQLパズル　p230 55 競走馬の入賞回数 の 解法2の学習メモです。

IN述語とGROUP BYの組み合わせですね。
自分的にはIN述語の動きを追うのに手間取りましたね。

# 要件
３つのカラムから集計値を求める。

今回の場合だと、3つのカラムwin_name,place_name,show_nameがある。
３つのカラムとも馬の名前が入っており　３つのカラムに対して馬の名前の集計値を取得したい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/4d1f1a43-39b7-9c55-45b2-82f184952190.png)



# SQL

## DDL
```sql
--  p228 55 競走馬の入賞回数
DROP TABLE IF EXISTS RacingResults;
CREATE TABLE RacingResults
(track_id CHAR(3) NOT NULL,
 race_date DATE NOT NULL,
 race_nbr INTEGER NOT NULL,
 win_name CHAR(30) NOT NULL,
 place_name CHAR(30) NOT NULL,
 show_name CHAR(30) NOT NULL,
    PRIMARY KEY (track_id, race_date, race_nbr));

DROP TABLE IF EXISTS HorseNames;
CREATE TABLE HorseNames
(horse CHAR(30) NOT NULL PRIMARY KEY);

INSERT INTO RacingResults VALUES(1, '2007-05-01', 1, 'A', 'B', 'C');
INSERT INTO RacingResults VALUES(1, '2007-05-01', 2, 'E', 'F', 'P');
INSERT INTO RacingResults VALUES(1, '2007-05-02', 1, 'B', 'C', 'A');
INSERT INTO RacingResults VALUES(2, '2007-05-02', 1, 'O', 'P', 'Q');
INSERT INTO RacingResults VALUES(2, '2007-05-02', 2, 'A', 'P', 'Q');

INSERT INTO HorseNames VALUES('A');
INSERT INTO HorseNames VALUES('B');
INSERT INTO HorseNames VALUES('C');
INSERT INTO HorseNames VALUES('D');
INSERT INTO HorseNames VALUES('E');
INSERT INTO HorseNames VALUES('F');
INSERT INTO HorseNames VALUES('O');
INSERT INTO HorseNames VALUES('P');
INSERT INTO HorseNames VALUES('Q');

```

## 答えのSQL

```sql
-- 55 競走馬の入賞回数　その2　p230
-- IN述語を使って、HorseNamesとRacingResultsの結合を行う
SELECT H1.horse, Count(*)
    FROM HorseNames AS H1, RacingResults AS R1
    WHERE H1.horse IN (R1.win_name,R1.place_name,R1.show_name)
    GROUP BY H1.horse;

-- FROM句でテーブルを結合して　クロス結合を作る
-- 
SELECT H1.horse,R1.win_name,R1.place_name,R1.show_name
    FROM HorseNames AS H1, RacingResults AS R1
    ;
-- 上で作ったクロス結合から　IN述語を使って条件指定する。
-- 　3カラムのうち一つでもhorseと同じ文字が入っている条件をもとめている
SELECT H1.horse,R1.win_name,R1.place_name,R1.show_name
    FROM HorseNames AS H1, RacingResults AS R1
    WHERE H1.horse IN (R1.win_name,R1.place_name,R1.show_name)
    ;

-- GROUP BY で部分集合を作り、Count(*)で部分集合との要素の個数を算出する。
-- 答え
SELECT H1.horse, Count(*)
    FROM HorseNames AS H1, RacingResults AS R1
    WHERE H1.horse IN (R1.win_name,R1.place_name,R1.show_name)
    GROUP BY H1.horse;

```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/d4314930-4ba9-2ce5-12d3-cb81b8607a18.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/ee338796-5644-0f45-99fb-bdec38d29aac.png)


# 参考

SQLパズル　p230

SQLパズル　サポートページ
https://mickindex.sakura.ne.jp/database/db_support_sqlpuzzle.html#LocalLink-p55

達人に学ぶSQL徹底指南書第２版　該当する場所なし。

postgresql IN述語 scalar form (2種類あるのか…知らんかった)
https://www.postgresql.jp/document/7.3/user/functions-subquery.html


テーブル結合はJOINとFROMどちらで行うべきか？   （MYSQLだけど...）
https://www.ritolab.com/posts/258#from-%E5%8F%A5%E3%81%A7%E3%81%AE%E7%B5%90%E5%90%88%E3%81%AF%E7%94%A8%E9%80%94%E3%81%8C%E9%99%90%E5%AE%9A%E7%9A%84


github差分

https://github.com/RYA234/SQL_Puzzle_Learning/commit/0f8d42900c080dd8a69b7a4f3d30aca1e3c706bd
2024/11/19主にITとかセキュリティの記事

FortiClient最新版に脆弱性、中国発DEEPDATAマルウェアがVPN認証情報を窃取(11/17)
https://innovatopia.jp/cyber-security/cyber-security-news/44762/

米国 NIST SP 800-172 Rev.3（初公開ドラフト） 管理対象非機密情報保護のための拡張セキュリティ要件(11/17)
http://maruyama-mitsuhiko.cocolog-nifty.com/security/2024/11/post-48c352.html

ランサム攻撃訓練の高度化でBCPを磨き上げる
中核システム停止時も業務継続できる態勢目指し(11/17)
https://www.risktaisaku.com/articles/-/97313

ランサムウェア 攻撃 グループ「BianLian」とは概要や事例を解説(11/17)
https://rocket-boys.co.jp/10613/

【基本から学ぶ】パスワード管理の重要性と選び方
https://cybersecurity-park.com/3321/

ダークウェブを体験してわかったマイナンバーカードがもつリスクと個人情報保護の対策(11/17)
https://dime.jp/genre/1882972/2/

ISEN、「学校・教育機関における個人情報漏えい事故の発生状況」調査報告書を公開(11/17)
https://www.kknews.co.jp/news/20241117o03

情報セキュリティ演習をサポートするプラットフォームが近日登場します(11/16)
https://www.vietnam.vn/ja/nen-tang-ho-tro-dien-tap-thuc-chien-an-toan-thong-tin-sap-ra-mat/

帝塚山学院大学、メールアカウントへ不正が発生し迷惑メール配信に悪用される(11/17)
https://rocket-boys.co.jp/10603/

【課題解決ページ】WordPress/CMSのセキュリティはどこまで行えばよいですか？(11/17)
https://www.prime-strategy.co.jp/information/wordpress-cms-sec/

ぶっちぎりで高い約18万円のX870Eマザーが発売、そのかわり自分だけのAIが作れるぞ！(11/16)
https://ascii.jp/elem/000/004/235/4235238/?rss

75歳の父が「スマホで支払いをしてみたい」と言いますが、スマホの操作に慣れていないため、誤操作などが不安です。高齢者でも始めやすいキャッシュレス決済はありますか？(11/17)
https://financial-field.com/living/entry-346926

マイナンバーカード利用時にトラブルが発生した時の平均被害額はなんと10万円超え(11/17)
https://news.yahoo.co.jp/articles/8731414cac6c7d351dc5442cca51d56af0be4d79?source=rss

ダークウェブを体験してわかったマイナンバーカードがもつリスクと個人情報保護の対策(11/17)
https://dime.jp/genre/1882972/

サイバー法案、野党と議論
自民幹部、早期成立目指す(11/16)
https://www.saitama-np.co.jp/articles/109866/postDetail
Javascriptライブラリ「node-fetch」が誕生した背景と目的

「node-fetch」は、Node.js環境で使用できるHTTPリクエストライブラリとして開発されました。その誕生の背景と目的について詳しく説明します。

---

### **背景**

1. **Node.js標準のHTTPモジュールの扱いにくさ**
   Node.jsには、HTTPリクエストを行うための標準モジュール（`http`や`https`）が最初から含まれていますが、これらのモジュールは低レベルで、直感的ではないインターフェースを提供しています。リクエストを送る際に多くの設定が必要であり、レスポンスの処理も非同期ストリームとして行う必要があります。これが原因で、簡単なHTTPリクエストを行うにも複雑なコードを書く必要がありました。
2. **ブラウザの**`fetch` **APIの人気**
   ブラウザ環境では、`fetch` APIが標準として広く使われています。このAPIはPromiseベースでシンプルかつ使いやすいため、JavaScript開発者に人気があります。しかし、Node.js環境では`fetch` APIが標準でサポートされていなかったため、同じコードをブラウザとNode.jsで共有するのが困難でした。
3. **サードパーティライブラリ（例: axios）への依存回避の要望**
   Node.js用のHTTPリクエストライブラリとして、`axios`など他のライブラリも存在しましたが、それらは独自のインターフェースを持ち、ブラウザ環境の`fetch`とは異なる書き方が必要でした。これにより、ブラウザとNode.jsで一貫したコードを書くのが難しいという課題がありました。

---

### **目的**

1. **Node.js環境での**`fetch` **API互換の提供**
   「node-fetch」は、ブラウザの`fetch` APIをNode.js環境で模倣する形で開発されました。これにより、ブラウザ用に書かれたコードをNode.js環境でもそのまま動作させることが可能になり、フルスタック開発者にとって非常に便利なツールとなりました。
2. **シンプルでモダンなHTTPクライアント**
   Promiseベースで、シンプルかつ直感的にHTTPリクエストを扱えるインターフェースを提供することを目指しました。Node.jsの初心者や従来のHTTPモジュールに慣れていない開発者でも、簡単にHTTPリクエストを送信できるようになっています。
3. **軽量かつシンプルな設計**
   「node-fetch」は軽量で依存関係が少ない設計となっており、単純にHTTPリクエストを扱いたい場合に最適化されています。他のライブラリに比べて基本的な機能にフォーカスし、過剰な機能を持たないシンプルさを維持しています。

---

### **意義**

「node-fetch」は、ブラウザとNode.jsでコードの互換性を高めることで、フルスタック開発の生産性を向上させました。また、PromiseベースのモダンなAPIを提供することで、Node.js開発者にとってHTTPリクエスト処理を簡単にしました。

現在（2023年以降）、Node.js自体が`fetch`をネイティブサポートし始めたため、`node-fetch`の役割は変わりつつありますが、依然として古いバージョンのNode.jsや特殊なユースケースで利用されています。
vercelでホスティングしているサーバーサイドアプリケーションからの外部通信を識別する方法

Vercelでホスティングしているサーバーサイドアプリケーションから外部サービスへ通信を行う際、その通信元を識別する方法について説明します。

1. **固定IPアドレスの取得**

Vercelのサーバーレス関数は動的なIPアドレスを使用するため、特定の固定IPアドレスからの通信を保証することはできません。そのため、外部サービス側で特定のIPアドレスのみを許可する設定（IPホワイトリスト）を行うことは困難です。

1. **認証情報の利用**

外部サービスとの通信を安全に行うためには、以下の方法を検討してください：

- **APIキーやトークンの使用**：外部サービスが提供するAPIキーやアクセストークンを利用し、認証を行います。
- **カスタムヘッダーの追加**：リクエストヘッダーに特定の値を追加し、外部サービス側でその値を検証することで、正規の通信元からのリクエストであることを確認します。

1. **Vercel Secure Computeの利用**

VercelのEnterpriseプランでは、Secure Compute機能を利用して、サーバーレス関数と外部サービス間でプライベートな接続を確立することが可能です。これにより、通信のセキュリティを強化できます。

**まとめ**

Vercelのサーバーレス関数から外部サービスへの通信元を識別するためには、固定IPアドレスの使用が難しいため、認証情報の適切な管理や、必要に応じてVercelの上位プランの機能を活用することが推奨されます。
Anacondaを用いてPythonをダウングレードする

gensimのインストールの際にPythonをダウングレードする必要性が生じ、四苦八苦しました。手順を備忘録としてまとめます。Windowsの内容になります。

# 1.Anacondaをインストールする
https://effegma.com/install-anaconda/

Anacondaプロンプトを使用するため、Anacondaをインストールします。Anacondaを用いることで、Pythonの異なるバージョンや、ライブラリなどをまとめた仮想環境を作成することができます。

# 2.Anacondaプロンプトを起動
Anacondaインストール後に起動するAnacondaNavigatorから、Anacondaプロンプトを起動します。
![スクリーンショット 2024-11-19 011049.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3890153/4482fb89-92a5-a344-f5df-5c40037575df.png)

Anacondaシェルという、Anacondaプロンプトと似たものがありそれでも同様のことができるのかもしれませんが、今回試していません。

# 3.Python仮想環境を作成・起動
以下をAnacondaプロンプトで実行し、仮想環境を作成・起動します。
```shell
conda create -n {任意の仮想環境名} python=3.xx  //バージョン3.xxのPython仮想環境を作成
conda activate {任意の仮想環境名}  //仮想環境を起動
```

仮想環境を起動後、pipやcondaコマンドを用いて必要なライブラリをインストールします。

仮想環境停止には、以下コマンドを実行します。
```
conda deactivate  //仮想環境を停止
```

# 4.VSCodeで仮想環境に接続
ある程度VSCodeでPythonの開発環境が整っていること前提ですが、VSCode右上からPythonの環境を選択することができます。
![スクリーンショット 2024-11-19 012545.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3890153/0dbf1287-4bf9-e6f7-d783-fadbbd82deb9.png)

こちらから、自分の作成した仮想環境名を探して選択すればOKです。

以上の手順により、任意の過去バージョンのPython仮想環境で作業することができるようになります。
一般公開しているWEB APIにおける不正アクセス対策

一般公開しているWEB APIにおける不正アクセス対策は、APIのセキュリティを強化し、不正利用を防ぐために重要です。以下に具体的な対策をいくつか挙げます。

---

### 1. **認証と認可の導入**

- **APIキー**
  クライアントに一意のAPIキーを発行し、それをリクエストに含めることでアクセスを制御します。
- **OAuth 2.0**
  権限を持つユーザーだけがアクセスできるように、OAuth 2.0などのトークンベース認証を利用します。
- **JWT（JSON Web Token）**
  セッションを維持せずにユーザーを認証するためにJWTを利用します。

---

### 2. **通信の暗号化**

- **HTTPSの使用**
  APIエンドポイントでHTTPSを強制することで、通信内容を暗号化し、中間者攻撃（MITM）を防ぎます。

---

### 3. **レート制限とスロットリング**

- **IPベースのレート制限**
  特定のIPアドレスからのリクエスト頻度を制限し、過剰なリクエストを防ぎます。
- **トークンベースのレート制限**
  ユーザーやアプリごとにリクエスト回数を制限する仕組みを導入します。

---

### 4. **入力データの検証**

- **パラメータバリデーション**
  リクエストのすべてのパラメータを検証し、不正な入力を拒否します。
- **SQLインジェクション対策**
  SQLインジェクション攻撃を防ぐためにプリペアドステートメントやORMを使用します。
- **JSONスキーマバリデーション**
  JSON形式のデータを受け取る場合、期待されるスキーマに基づいてデータを検証します。

---

### 5. **クロスオリジンリソース共有（CORS）設定**

- **ホワイトリスト方式**
  許可するオリジンを明示的に指定し、不要なドメインからのリクエストを拒否します。

---

### 6. **ロギングとモニタリング**

- **リクエストログの収集**
  すべてのリクエストをログに記録し、異常なパターンを検出できるようにします。
- **セキュリティイベントの監視**
  セキュリティ関連のイベント（異常な認証試行や大量のリクエストなど）を監視し、即座に対応できるようにします。

---

### 7. **WAF（Web Application Firewall）の導入**

- WAFを利用して、一般的な攻撃（SQLインジェクションやクロスサイトスクリプティングなど）をブロックします。

---

### 8. **IP制限と地理的フィルタリング**

- **IPアドレスのホワイトリスト/ブラックリスト**
  許可されたIPアドレスだけがアクセスできるように制限します。
- **地理的な制限**
  必要に応じて特定の地域からのアクセスを制限します。

---

### 9. **トラフィックの分析とボット対策**

- **CAPTCHAの導入**
  ユーザーが人間であることを確認するためにCAPTCHAを利用します。
- **ボット検出ツール**
  Bot Managementツール（例：Cloudflare Bot Management）を活用して、悪意のあるボットからのアクセスをブロックします。

---

### 10. **定期的なセキュリティテスト**

- **ペネトレーションテスト**
  定期的にペネトレーションテストを実施して脆弱性を発見します。
- **脆弱性スキャン**
  静的コード解析ツールや動的アプリケーションセキュリティテスト（DAST）を使ってセキュリティリスクを特定します。

---

これらの対策を組み合わせて実施することで、APIのセキュリティを大幅に向上させ、不正アクセスのリスクを軽減できます。
Goで出るエラーや警告を直そう：変数宣言と代入を別にした時

### 概要

Goで変数宣言と宣言した変数に値を代入する処理を、2行にして書いたとき出る警告の解決方法

### 警告が出た処理

以下のソースを書くと「should merge variable declaration with assignment on next line (S1021)」という警告が出る。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926100/aaff3560-b5ba-887d-2d57-ce97542bb9d8.png)

### 警告が出る理由

この警告は「変数の宣言と代入を次の行にまとめるべきだ」という意味の警告。次のようなGoの設計思想により表示される

1.明瞭性と簡潔さ
Go言語は、コードをシンプルかつ明確に保つことを重視しているため

2.エラーチェックの促進
変数の宣言と代入が異なる行にあると、意図せず未使用の変数が生じるなど、エラーの原因となりやすいため

3.一貫性
Goは、コードの書き方について一つのスタイルを守り、チームの協力やメンテナンスを容易にすることを重視しているため

### 警告の解決方法

変数宣言と値の代入を同時に書くと警告が解消される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926100/9a8435a3-c352-e679-46fa-1917b440d55e.png)
【Win / Mac】Pythonでプロセスの多重起動を防止する

# 目標

```python
singleton()  # 既に同じプロセスが存在する場合はここで終了。なければスルー。
```

# 環境構築

標準ライブラリのみで動作するため、追加のインストールは必要ありません。

# コード

```python
import sys

if sys.platform == "win32":
    import ctypes

    UNIQUE_STRING = "このアプリでしか使われないであろう、一意の文字列"

    def singleton():
        Kernel32 = ctypes.windll.Kernel32
        mutex = Kernel32.CreateMutexA(0, 1, UNIQUE_STRING)
        result = Kernel32.WaitForSingleObject(mutex, 0)
        if result == 0x00000102:
            sys.exit(-1)

elif sys.platform == "darwin":
    import subprocess
    from os import path
    import __main__

    def singleton():
        if getattr(sys, "frozen", False):
            file_name = "ビルド後のアプリ名(hoge.appならhoge)"  # nuitkaやpyinstallerでビルドする場合
        else:
            file_name = path.basename(__main__.__file__)  # Pythonインタープリタから実行する場合
        p1 = subprocess.Popen(["ps", "-ef"], stdout=subprocess.PIPE)
        p2 = subprocess.Popen(["grep", file_name], stdin=p1.stdout, stdout=subprocess.PIPE)
        p3 = subprocess.Popen(["wc", "-l"], stdin=p2.stdout, stdout=subprocess.PIPE)
        p1.stdout.close()
        p2.stdout.close()
        output = p3.communicate()[0].decode("utf8").replace("\n", "")
        if int(output) > 2:
            sys.exit(-1)
```

# 解説
割愛（リクエストがあれば書きます）

# 謝辞

上記のコードの中には私が書いたものだけではなく、ネットを彷徨って見つけたコードのコピペも紛れています。それらのページを見つけることができなかったので出典がありません。原作者の方ごめんなさい。
もしコピペ元だと思われるページを見つけた方は教えていただけるとありがたいです。
外部APIの情報を取得したい！

こんにちは。開発会社で自社サービス開発に携わっているもけです。
そのサービスで外部APIから提供される市町村データを使用していましたが、
その置き換え対応でつまづいたところがありました。
備忘録を兼ねてどのような対応をとったかを記します。

# 経緯
作っているwebアプリケーションで市町村情報を取得するのに使っていたAPI（[RESAS API](https://opendata.resas-portal.go.jp/)）が提供終了するので代替のAPI([国土交通DPF利用者API](https://www.mlit-data.jp/api_docs/))に置き換えようとした。

# 手順
1. [国土交通DPF利用者APIの利用方法](https://www.mlit-data.jp/api_docs/reference/general/apiaccess.html)をもとに、アカウント登録をする
1. RESAS APIを使っているところを国土交通DPF利用者API(以降「代替API」と表記)に置き換える
    - 登録時に発行される接続情報などをアプリ側に登録していく
1. 代替APIに合わせてリクエスト時に投げる情報とレスポンスで受け取る情報の形式を見直す

# 詰まったところ
手順3のところでクライアント側から直接代替APIにPOST送信でリクエストを投げたところ、CORSエラーが発生してしまった。

### CORSって？
- CORS（クロスオリジンリソース共有）はアプリケーションを統合するためのメカニズム
- 特定のドメインにロードされたクライアントウェブアプリケーションが**異なるドメイン内のリソースと通信する方法を定義する**仕組みのこと。　※1
- CORSを使用すると、ウェブサーバーはリソースへのクロスオリジンアクセスを許可するか、明示的に選択することができ、他の許可外のリクエストを拒否することができるようになる

### CORSエラー　
- 許可外のドメインにアクセスしようとした場合、または上記CORSの構成が正しくされていない場合、CORSセキュリティルールに違反したとして、CORSエラーが発生する
- この正しく構成されていないというのは、必ずしも設定をミスしてしまっているわけではなく、ユーザー意図的にリクエストを拒否している場合もあるので、意図的に許可外にしていないか、ウェブシステムの構成の背景を踏まえて改善する必要がある
※2※3

# 状況
今回の原因は代替API側でCORSによるアクセスを許可されていないからではないかと考えられる
- 作っているwebアプリケーション側の設定を確認すると、axiosのwithCredentialsをtrueに設定している
    - このオプションがtrueになっている場合、APIにアクセスするときは、CORSの仕組みを利用して対象にアクセスしようとする
    - この場合代替API側でもCORSによるアクセスを許可されていないといけないが、おそらく今回は許可されておらず、それによりエラーが発生すると考えた

そのため、アクセスする際にCORSを使わないリクエストを送る方法があればできるのではと考えた。

# 解決法
解決するためのアイデアは以下の2つである。

**案1：クライアント側でaxiosのCORSを使わないリクエストを送るようにする**

**メリット**
- レスポンスが速い
- サーバーへの負荷が少ない

**デメリット**
- CORS制限を受けやすい
- 今回対応する部分だけ、axiosのwithCredentialというオプションを外す必要があり、個別の対応になるため、将来的なメンテナンス性が下がる原因になる
- 案2に比べるとセキュリティ面で不安がある

**案2：サーバー側のすでにCORSでクロスドメインアクセス許可済みのAPIを経由して代替APIを呼び出すようにし、アクセス時にCORSを使わなくていいようにする。**

**メリット**
- CORS制限を受けにくい
- 他実装部分と対応を変える必要がないため、メンテナンスがしやすい
- 重要情報の管理など、セキュリティが高い

**デメリット**
- レスポンスが遅い可能性あり
- サーバーへの負荷が多い

いずれの策も取ること自体は可能であったが、メリットデメリットを考慮した結果、
今回は案2を選択した。
この対策により、代替APIへのアクセスが可能になった。

# 終わりに
今回の対応ではレスポンス面での課題が残ったが、これは作っているwebアプリケーション内における情報取得の仕方やその情報の保持方法で改善が見込めそうだったので、今後改善に取り組む。

# 参考
※1
https://aws.amazon.com/jp/what-is/cross-origin-resource-sharing/
※2
https://developer.mozilla.org/en-US/docs/Glossary/CORS
※3
https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS/Errors
野獣先輩は何人の命を救っているのか


## 前書き

〇という漢字は攻撃力が高いため、〇と表記します。

## 計算式

```
野獣先輩が救った命 = (自〇しようと思った人数 - 実際に自〇した人数) * 自〇しようと思っている期間に野獣先輩を摂取する割合 * 野獣先輩で思いとどまれる確率
```

## 求める

野獣先輩の知名度が上がってきたのが2014年頃らしいので、2014年のデータで考える。

警視庁のデータ[^1]によると2014年には25,427人が自〇したそうだ。

[^1]: https://www.npa.go.jp/safetylife/seianki/jisatsu/H26/H26_jisatunojoukyou_01.pdf

自〇しようと思った人の総数はどのくらいいるのか分からないが、2014年はうつ病患者が729,000人[^2]だそうなので、その100分の1である72,900人であると仮定する。

[^2]: https://www.m3.com/clinical/open/news/665145

私が学生時代の時に30人のクラスに3人くらいは野獣先輩のことを認知していたため、10代の野獣先輩の認知率は10分の1程度だと思われる。
そこから様々な年代を考慮して野獣先輩の認知率を50分の1とする。

この上で自〇しようと思っている期間に野獣先輩を摂取する割合は、相当な野獣先輩愛好家であることを考慮し、200分の1であると仮定する。

最後に、野獣先輩で思いとどまれる確率は2分の1だとする。

以上より、2014年で野獣先輩が救った命は…

```math
\begin{eqnarray}
\text{野獣先輩が救った命} & = & (\text{自〇しようと思った人数} - \text{実際に自〇した人数}) \\
& & \times \text{自〇しようと思っている期間に野獣先輩を摂取する割合} \\
& & \times \text{野獣先輩で思いとどまれる確率} \\
& = & (72900 - 25427) \times \frac{1}{200} \times \frac{1}{2} \\
& \approx & 119
\end{eqnarray}
```

約119人だと予測される。

## 補足

Q. 野獣先輩で思いとどまれかなった場合、自〇してしまうのでは？（計算方法がおかしいのでは？）
A. その場合は、別の要因で自〇を回避していると考えてください。
Which OS is better, Windows, macOS, or Linux?

Windows is versatile and widely compatible . It is great for gaming, general use, and business applications. Mac OS X offers a user-friendly experience with robust software for creative professionals. Linux excels in customization and security.

That depends. Those operating systems require some degree of computer proficiency. If you aren’t very PC savvy or have no tech person to help you out, I wouldn’t recommend Linux. If you are a gamer, I wouldn’t recommend Linux and Mac OS. For ease of use, Mac OS and Windows are general go-to operating systems. Linux has its different flavors and distributions for beginners, though but I still wouldn’t recommend it if you are new to using computers.

![2222.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3937793/13329766-f68b-6090-eff5-46f7bd0a67e1.jpeg)

Mac OS is sort of limited. Gaming isn’t an option for Mac, Linux allows some gaming (either that is native or via Steam) and Windows is the best OS for gamers because virtually all games created (for personal computers) supports Windows.

For lightweight and speedy operating systems, that seems to the specialty of Mac. Windows tends to be sluggish. Linux performance bases solely on how the user optimizes their system.

Now this is my favorite part: security. Linux would win this time because 1. Not a lot of Linux viruses out there, 2. Linux restricts access to its ‘root’ user, meaning that in the event that your computer is infiltrated, your computer won’t be totally damaged and your system files would still be ok . 3. Linux encourages its users to use the tools within their software repository. Sort of like getting your apps from the App Store rather than downloading them off a shady website. Windows is really pretty much the target of modern day malware so security is pretty bad for Windows. mac OS I think has pretty decent security. Can’t really comment much about it.

Far as customisability goes, mac OS loses as you cannot modify your computer because of proprietary reasons. Windows allows some sort of customization but Linux allows anything whatever the user wants it to be because it is open source and you can edit the code for your OS.

Well I am not sure if the answer I wrote there is what you are looking for but I hope it helps in some way. :)

Edit: It is also important to note that Windows has a large number of support from its community because about more than 80% of the world’s computer systems use Windows. I think Windows is the best operating system for users who are starting to learn about PCs. Linux is the best operating system for advanced users and everyday tasks. MacOS is great for speed and ease of use as well.


Linux is the worst OS for first time users. Windows is the worst OS for security. macOS is the worst system for customization and gaming.
【合格体験記】AWS Certified AI Practitioner(正式版)に合格しました(2024/11/04)【AIF-C01】

# 目次
[#1.はじめに](#1はじめに)
[#2.筆者のスペック](#2筆者のスペック)
[#3.学習内容](#3学習内容)
[#4.試験当日](#4試験当日)
[#5.あとがき](#5あとがき)

# 1.はじめに

題名の通り、AWS Certified AI Practitioner(正式版)に合格しました。

https://twitter.com/ss_IT_study/status/1853417951078256732

正式版の合格体験記はあまりなさそうなので、記録を残しておこうと思います。
※Xの投稿の通り同じ日にCLFも受験したのですが、その件は別記事で

# 2.筆者のスペック

* 大学は情報系
* SIerで10年程度勤務
* AWSの利用経験は2年程度
* AWS SAA取得済み([【合格体験記】AWS Certified Solutions Architect - Associateに合格しました(2022/11/19)【SAA-C03】](https://qiita.com/ss_IT_study/items/d14b81ea4c92ced86786))
* AWS DVA取得済み([合格体験記】AWS Certified Developer - Associateに合格しました(2023/02/23)【DVA-C01】](https://qiita.com/ss_IT_study/items/ae5e612f6f0affe7bf8a))
* AWS SAP取得済み([【合格体験記】AWS Certified Solutions Architect - Professionalに合格しました(2024/03/16)【SAP-C02】](https://qiita.com/ss_IT_study/items/3f9ba1321476e2b8bc9e))
* AWS SCS取得済み([【合格体験記】AWS Certified Security - Specialtyに合格しました(2024/06/30)【SCS-C02】](https://qiita.com/items/2cc0321223e0022e5b6e))
* AWS SOA取得済み([【合格体験記】AWS Certified SysOps Administrator - Associateに合格しました(2024/08/10)【SOA-C02】](https://qiita.com/ss_IT_study/items/816230059ad07d0679bc))

# 3.学習内容
①[AWS Certified AI Practitioner (AIF-C01) 試験ガイド ](https://d1.awsstatic.com/ja_JP/training-and-certification/docs-ai-practitioner/AWS-Certified-AI-Practitioner_Exam-Guide.pdf)

まずは試験ガイドを読み込み、範囲を把握しました。
特に付録に記載されているサービスでわからないものは概要の説明できるようにメモとしてまとめました。

②[Standard Exam Prep Plan: AWS Certified AI Practitioner (AIF-C01)](https://explore.skillbuilder.aws/learn/lp/2193/standard-exam-prep-plan-aws-certified-ai-practitioner-aif-c01)

SkillBuildersの無料コンテンツです。
AIFは開始したばかりであまり学習コンテンツが充実していないので、公式ソースを元に体系的に勉強しました。
Prep Planは英語版しかなかったのですが、紐づいているコンテンツは大体日本語版が提供されているので、リンクを飛んで言語を変更して登録しなおしていました。
AWSのサービスだけでなく、一般的なAIや機械学習についても学習できます。


③[Exam Prep Official Practice Question Set: AWS Certified AI Practitioner (AIF-C01 - Japanese)](https://explore.skillbuilder.aws/learn/course/19791/exam-prep-official-practice-question-set-aws-certified-ai-practitioner-aif-c01-japanese)

こちらもSkillBuildersの無料コンテンツです。
20問無料で問題演習ができます。
AIF、MLAで追加された新しい出題方式の確認や解説ページの詳細確認を反復しました。


# 4.試験当日
過去の試験と同様にテストセンターを予約の上受験しました。
予約より少し早めに到着したところ、試験自体も少し早く開始できました。
初受験なので見直しも慎重に行いましたが、それでも50分程度は余って退出しています。

CLFでは受験後すぐに画面上に合否が出力されるみたいですが、
AIFでは試験終了後即時結果が分かるわけではなく、
しばらく経ってから試験履歴が更新されました。
※ざっくりですが、10:00開始の試験を受けて20:00くらいに結果が閲覧可能になったと思います

# 5.あとがき
AWS AIF(AIF-C01)の合格体験記でした。
次はMLAかDEAを受けようと考えていますが、2025/03までに全冠達成はかなり頑張らないと厳しそうですね。
Nginxプロセスの「IO write count」とは？増減から推察できること

**Nginxプロセスの「IO write count」**は、Nginxプロセスがディスクやストレージにデータを書き込んだ回数を示すメトリックを指します。この情報は、Linux環境で`/proc/[pid]/io`や`iostat`、`pidstat`などのツールで確認することができます。

---

### IO write countの意味

1. **定義**
   IO write countは、Nginxが以下のような操作を行った際にカウントが増加します：
   - ログファイル（アクセスログやエラーログ）への書き込み。
   - キャッシュファイルの生成または更新。
   - 一時ファイルの書き込み（アップロードされたデータやプロキシによる一時データ）。
   - ディスクへのバッファフラッシュ。
2. **単位**
   - **書き込みの回数**を示しており、書き込んだデータの量（バイト数やメガバイト数）ではありません。
   - 実際の書き込み回数は、Nginxの設定やシステムのI/Oスケジューリングに依存します。

---

### この数値の増減から推察できること

IO write countの増減は、Nginxがディスク書き込み操作にどの程度依存しているかを示し、システムの状況を把握するのに役立ちます。

#### **1. 数値が多い場合**

- **高頻度なログ出力**
  アクセスログやエラーログが頻繁に書き込まれている可能性があります。特に高トラフィック時にはこの値が増加します。
- **キャッシュ書き込み**
  `proxy_cache`や`fastcgi_cache`が有効になっており、新しいキャッシュファイルが頻繁に生成されている。
- **一時ファイルの利用**
  大きなリクエストやレスポンスが一時ファイルとしてディスクに保存されている可能性。
- **高トラフィックによるディスクI/O増加**
  クライアントからの大量のリクエスト（特に書き込み操作を伴うもの）がディスクの使用を増加させている。

#### **2. 数値が少ない場合**

- **低トラフィック**
  サーバーのリクエスト数が少ない。
- **ログ出力の抑制**
  ログレベルが低く設定されている（例：`error_log`が`warn`や`crit`に設定されている）。
- **キャッシュヒット率が高い**
  ディスクに新しいキャッシュを書き込む必要が少ない場合。
- **一時ファイルの使用が減少**
  一時ファイルに依存せず、メモリ内で処理できている。

---

### IO write countを活用する場面

#### **1. パフォーマンスの最適化**

- **ログの最適化**
  高トラフィック時にはアクセスログの書き込みが負荷になることがあるため、以下の方法で最適化できます：
  - 不要な詳細ログを無効化（`log_format`や`access_log`の最適化）。
  - ログのバッファリングを有効化（`access_log`の`buffer`オプション）。
- **キャッシュの効率化**
  キャッシュ書き込みが多すぎる場合、キャッシュポリシー（キャッシュサイズや有効期限）を見直す。

#### **2. 問題の特定**

- **ディスクI/Oのボトルネック**
  IO write countが高く、ディスクI/Oがシステムのボトルネックとなっている場合、SSDへの移行やディスク性能の改善を検討。
- **不必要な書き込みの削減**
  頻繁に無駄なキャッシュや一時ファイルが生成されていないか確認。

#### **3. リソースの監視**

- **一時ファイルの使用量確認**
  `proxy_temp_path`や`client_body_temp_path`に多くの書き込みが発生している場合、大きなリクエストやレスポンスに依存するワークロードがあることを示唆。
- **ログ量の監視**
  ログの書き込みがディスクの主要な負荷要因である場合、ログのローテーション間隔や削除ポリシーを調整。

---

### 結論

Nginxの「IO write count」は、ログやキャッシュ、一時ファイルの生成といったディスク書き込み動作を把握するための指標です。この数値を監視することで、以下が可能です：

- パフォーマンス問題の特定（特にディスクI/O負荷）。
- キャッシュやログ設定の最適化。
- 一時ファイル使用量やストレージの効率改善。

特に高負荷環境では、IO write countの変動がサーバー性能に与える影響を注視することで、効果的な改善策を講じることができます。
golang-standasrds/project-layout を理解する

# golang-standards/project-layout

golang-standards/project-layout とは Go プロジェクトの基本的なディレクトリ構成を定義したものです。
Go 公式で定義しているものではありません。

https://github.com/golang-standards/project-layout

## リポジトリの解説

ディレクトリの説明はルートの README に記載があります。
README は多数の言語に対応しており、日本語も対応しているようです。

日本語の README:

https://github.com/golang-standards/project-layout/blob/master/README_ja.md

また、各ディレクトリにも README が存在しており、例が記載されていることもあります。

# 各ディレクトリについて

## `/api`

OpenAPI 定義などを置くディレクトリ。

## `/assets`

画像などを置くディレクトリ。

## `/cmd`

Go における main 関数を置くディレクトリ。
このディレクトリに置いた main 関数から `/internal` や `/pkg` にアクセスします。

## `/configs`

設定を管理するディレクトリ。

## `/deployments`

デプロイメント設定を置くディレクトリ。

## `/docs`

設計などドキュメントを置くディレクトリ。

## `/examples`

ライブラリとしてリポジトリを公開した際にライブラリの利用例を置いておくようです。

## `/githooks`

Git のフックを置くディレクトリ。

## `/init`

システム init を置くディレクトリ。

## `/internal`

Go 1.4 から言語仕様上、特別なパッケージなようです。

https://go.dev/doc/go1.4#internalpackages

## `/pkg`

ライブラリコードを置くディレクトリ。

## `/scripts`

スクリプトを置くディレクトリ。
プロジェクトルートに存在する Makefile からこのディレクトリに置いてあるスクリプトを呼び出すことで Makefile をシンプルにすることができます。

## `/test`

テストコードやテストに使用するデータを置くディレクトリ。

## `/third_party`

サードパーティのコードを置くディレクトリ。

## `/tools`

Go プロジェクトをサポートするツールを置くディレクトリ。

## `/vendor`

依存関係を管理するディレクトリ。
`go mod vendor` を実行するとこのディレクトリが作成されます。

## `/web`

Web アプリケーションに関するコードを置くディレクトリ。

## `/website`

Web サイトのデータを置くディレクトリ。
【ffmpeg】変換時にフレームレートを指定する方法

`ffmpeg` コマンドを使用すると動画をGIFなどに変換できます。

https://ffmpeg.org

## インストール方法

以下のコマンドを実行してインストールします。

```terminal
brew install ffmpeg
```

https://formulae.brew.sh/formula/ffmpeg

### フレームレートを指定する方法

フレームレートを指定するには `-r` を使用します。

```terminal
ffmpeg -i input.mp4 -r 10 output.gif
```

上記の場合、フレームレートは 10 fps になります。
適合率と再現率とF1スコア（メモ）

# 適合率・再現率
機械学習などで，モデルの評価に使われる指標。

# いきなりまとめ
- 適合率（Presision）を高めにするモチベーション

誤って「真」と判断することが重大な影響を及ぼすケースを減らしたい。
モデルが「真」と判断して，実は「偽」だったケースを減らしたい。
モデルが「偽」として，実は「真」だったという見逃しは多くてもよい。

- 再現率（Recall）を高めにするモチベーション

怪しいものをまずは一旦あぶり出したい場合。
見逃しが重大な影響を及ぼすケースを減らしたい。
モデルが「偽」と判断して，実は「真」だったケースを減らしたい。
モデルが「真」と判断して，次は「偽」だった過剰反応は多くてもよい。

- F1スコアを高くするモチベーション
再現率と適合率，どちらも高くして優等生なモデルを作りたい。

# 適用例

- スパムフィルタ（スパムであれば「真」と判定するモデル）　→適合率を高くする

適合率が低いと，通常のメール（偽）がスパム（真）と判定されることが増える。

- Webフィルタ（危険なサイトであれば「真」と判定するモデル）　→適合率を高くする

適合率が低いと，通常のサイト（偽）が危険なサイト（真）と判定されることが増える。

- 癌の検査（癌であれば「真」と判定するモデル）　→　再現率を高くする

再現率が低いと，癌（真）なのに癌でない（偽）と判定してしまうこと（見逃し）が増える。

- セキュリティインシデントの検知（インシデントであれば「真」と判定するモデル）　→　再現率を高くする

再現率が低いと，インシデント（真）なのにインシデントでない（偽）と判定してしまうこと（見逃し）が増える。


# ひとりごと
真(true)が，必ずしも人の感覚に正しい事象のことを言わないのでややこしいです。どちらかというと，人間にとってよくない事象を「真」とすることが多いような（癌とか危険なサイトとかインシデントとか）

# 参考
https://www.renewable-energy-potential.env.go.jp/RenewableEnergy/dat/report/r03-01/r03-01_chpt3_Part2.pdf
DenoでWebGPUによる計算処理

「[Rustのwgpuで計算処理](https://qiita.com/fits/items/0fe661d27e5c41233644)」と同じ計算処理を Deno（2.0.6）で WebGPU を使って実装してみました。

多少の違いはあるものの概ね同じ API で処理を組み立てる事ができ、WGSL（WebGPU Shading Language）はそのまま使えました。[^1]

[^1]: WGSL はその名の通り WebGPU のためのものなので当然ではありますが

Adapter や Device は以下のように取得できるので、特にライブラリ等を使う必要もありませんでした。

```typescript:GPUAdapterとGPUDeviceの取得例
const adapter = await navigator.gpu.requestAdapter()
const device = await adapter?.requestDevice()
```

# 実装

TypeScript による実装結果はこのようになります。

```typescript:sample.ts
const workGroupSize = 4

const adapter = await navigator.gpu.requestAdapter()
const device = await adapter?.requestDevice()

if (!device) {
    console.error('not found device')
    Deno.exit(0)
}

const input = new Uint32Array([1, 2, 3, 4, 5, 6, 7, 8])

console.log(`input: ${input}`)

// WGSL
const wgsl = `
@group(0) @binding(0)
var<storage, read_write> data: array<u32>;

@compute @workgroup_size(${workGroupSize})
fn main(@builtin(global_invocation_id) global_id: vec3<u32>) {
    data[global_id.x] = 3u * data[global_id.x] + 1u;
}
`

const shader = device.createShaderModule({
    code: wgsl
})

// コンピューティングパイプラインの作成
const pipeline = await device.createComputePipelineAsync({
    layout: 'auto',
    compute: {
        module: shader,
        entryPoint: 'main'
    }
})

// ストレージバッファの作成
const storageBuf = device.createBuffer({
    mappedAtCreation: true,
    size: input.byteLength,
    usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC
})
// ストレージバッファへの書き込み
const data = new Uint32Array(storageBuf.getMappedRange())
data.set(input)
storageBuf.unmap()

// 出力用バッファ作成
const outputBuf = device.createBuffer({
    size: storageBuf.size,
    usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST
})

// バインドグループ作成
const bindGroup = device.createBindGroup({
    layout: pipeline.getBindGroupLayout(0),
    entries: [
        {
            binding: 0,
            resource: {
                buffer: storageBuf
            }
        }
    ]
})

const encoder = device.createCommandEncoder()

const pass = encoder.beginComputePass()
pass.setPipeline(pipeline)
pass.setBindGroup(0, bindGroup)
pass.dispatchWorkgroups(input.length / workGroupSize)
pass.end()

// ストレージバッファの内容を出力用のバッファへコピー
encoder.copyBufferToBuffer(storageBuf, 0, outputBuf, 0, storageBuf.size)

device.queue.submit([encoder.finish()])

await outputBuf.mapAsync(GPUMapMode.READ)

const output = new Uint32Array(outputBuf.getMappedRange())

console.log(`output: ${output}`)

outputBuf.unmap()
```

wgpu版との主な違いは下記のようになっています。

* バッファの作成と初期化を行う wgpu の ```create_buffer_init``` に相当する API が無さそうだったので、バッファ作成後に値を書き込み
* コンピューティングパイプライン作成時の ```layout``` に ```'auto'``` を指定
* ```Uint32Array``` を使ってバッファを処理
* GPUQueue は ```GPUDevice.queue``` で取得

# 実行

実行結果はこのようになります。

```sh:実行結果
$ deno run sample.ts
input: 1,2,3,4,5,6,7,8
output: 4,7,10,13,16,19,22,25
```
スクリプト20241118＿リクエストカウント

```
# 検索するディレクトリのパス
$prefix_directory = "D:\ドキュメント\個人work\01‗work\02_IT関連\20241118_リクエスト数カウントスクリプト"

# 検索するディレクトリのパス
$directory = "${prefix_directory}\target"

# キーワードファイルと除外キーワードファイルのパス
$searchKeywordsFile = "${prefix_directory}\keyword\search_keywords.txt"
$excludeKeywordsFile = "${prefix_directory}\keyword\exclude_keywords.txt"

# 外部ファイルからキーワードを読み込み
$searchKeywords = Get-Content -Path $searchKeywordsFile
$excludeKeywords = Get-Content -Path $excludeKeywordsFile

# キーワードごとのヒット件数を記録するためのハッシュテーブルを初期化
$keywordCounts = @{}

# キーワードをハッシュテーブルに初期化（カウント0で設定）
foreach ($keyword in $searchKeywords) {
    $keywordCounts[$keyword] = 0
}

# ディレクトリ内のすべてのaccessログを検索
Get-ChildItem -Path $directory -Filter access.* -Recurse | ForEach-Object {
    $file = $_.FullName
    # ファイル内の内容を読み込み
    $lines = Get-Content -Path $file

    # 除外キーワードを含まない行をフィルタリング
    $filteredLines = $lines | Where-Object {
        $excludeMatch = $false
        foreach ($exclude in $excludeKeywords) {
            if ($_ -match $exclude) {
                $excludeMatch = $true
                break
            }
        }
        -not $excludeMatch
    }

    # フィルタリング後の行に対して各キーワードのヒット件数をカウント
    foreach ($keyword in $searchKeywords) {
        $count = ($filteredLines | Where-Object { $_ -match $keyword } | Measure-Object).Count
        $keywordCounts[$keyword] += $count
    }
}

# キーワードごとのヒット件数を出力
Write-Host "Keyword Match Counts:"
foreach ($keyword in $keywordCounts.Keys) {
    Write-Host "${keyword}: $($keywordCounts[$keyword])"
}
```
基本情報技術者に向けて　Part.7

# データを整列させるアルゴリズム
## 基本交換法（バブルソート）
隣接するデータの代償を比較し、入れ替えることで全体を整列させる。
4213　先頭二つを比較
↓
2413　先頭二つを入れ替え
↓
2143　入れ替えたうちの右側と隣接する数字を入れ替え
↓
2134　上記と同じ処理を行う（右端はこれ以上数字がないのでこれで確定）
↓
2134　先頭二つを比較
↓
1234　先頭二つを入れ替え
↓
1234　入れ替えた数字を比較した際に右側が大きいのでこれで確定

## 基本選択法（選択ソート）
データの中から最小値もしくは最大値のデータを取り出し、先頭のデータと交換する。これを繰り返し全体を整列させる。
4213　対象の中から最小値を見つける
↓
1243　最小値と先頭のデータを入れ替え
↓
1243　先頭が確定
↓
1243　残りのデータから最小値を探す
↓
1243　今回は2が最小値だが入れ替えはなし（２が確定）
↓
1243　残りのデータから最小値を探す
↓
1234　最小値と先頭データを入れ替え


## 基本挿入法（挿入ソート）
整列済みのデータとみ整列のデータを分ける
未整列の側からデータを一つずつ整列済みの列の適切な位置に挿入し、全体を整列させる
4_213　先頭を整列済みとする
↓
4_213　未整列の数字（今回は2）をどこに挿入するか考える
↓
24_13　未整列の数字（今回は2）を挿入する
↓
24_13　次の未整列の数字（今回は1）をどこに挿入するか考える
↓
124_3　未整列の数字（今回は1）を挿入する
↓
124_3　未整列の数字（今回は3）をどこに挿入するか考える
↓
1234_　未整列の数字（今回は3）を挿入する

##　シェルソート
一定間隔沖に取り出した要素で部分列を作り、それぞれ整列して元に戻す
今度はさらに間隔を詰めて要素を取り出し、再度整列。
これを間隔が1になるまで繰り返す。
14725836    要素を四つおきに取り出す
↓
15_48_73_26　取り出した結果
↓
15_48_37_26　整列
↓
15483726　一つに戻す
↓
1432_5876　二つおきに取り出す
↓
1342_5786　整列

## クイックソート
中間的な基準値を決め、それより小さいグループ、それより大きいグループに分ける
その後、それぞれのグループでまた基準値を決めて振り分ける、これを繰り返す
14725836        基準値を決める

123_4_7586　　　基準値をベースに小さいグループと大きいグループに分け、基準値ごとに分ける

1_2_3_4_5_6_78　基準値をベースに小さいグループと大きいグループに分ける

1_2_3_4_5_6_7_8　上記の手順を繰り返す

## ヒープソート
未整列の部分を順序木という木構造に構成し、最大値か最小値を取り出し手整列済みの側へと移す
これを繰り返す整列
BigQueryのWHERE句の順番には気を付けようというお話

RDBMSで動かしていたクエリをそのままBigQueryに移行したらなんか遅い…と思って調べたところBigQueryはWHERE句の条件が複数あっても順番は最適化してくれないらしい。

**BigQueryのwhere句で複数条件を記載すると上から順番に実行されるので、効率良くデータを絞り込めるように順番を考えてクエリを作らなければパフォーマンスが落ちてしまう。**
~~大事な情報だからもっとわかりやすいところに書いておいてほしい~~

https://cloud.google.com/blog/ja/topics/developers-practitioners/bigquery-admin-reference-guide-query-optimization
>  式の順番が重要: BigQuery は WHERE 句で指定されている式の順序が最適だと想定し、式の順序を変更することはありません。WHERE 句には、最もデータを絞り込むことのできる式を最初に並べる必要があります。

自分の場合はWHERE句の順番を変えることで数分かかっていた処理が数秒ほどで終わるようになりました。
tool and key word AI(17)

# web

# mail
Web mail
mail tool

# omnicampus
# slack
home
DM;Direct Message
activities
後で
その他

# google

## google drive

## Gemini
gemini
https://deepmind.google/technologies/gemini/

# zenn

# Youtube
企画によって１週間後くらいに掲載

# discord

# keyword
LLM:Large Language Model
BERT
Fineturning
GPU
grep
VSCodeでVSCode Extension実装入門（ステップ２ コマンドパレットでHello World!）

 はじめに
VSCode(Visual Studio Code)でVSCode用のExtensionを実装してみる入門のステップ２です。とっかかりとしてステップ１ではVSCode Extensionプロジェクトのテンプレートを生成してみましたので、今回はデバッグ実行の事始めです。コマンドパレットでHello World!してみます。

# 前提条件
Windows11 Pro 22H2 22621.4169
VSCode(Visual Studo Code)　1.95.1
node 20.10.0
npm 10.9.0

# プロジェクトのフォルダ構成

お手数ですが[ステップ１](https://qiita.com/mylifewithviolin/items/36a39d760e06983a694c)をご参照ください。

# extension.ts
プロジェクトのテンプレートで生成されたextension.tsから英文のコメントを削除し、下記のようにコンソールログ出力とコマンドパレットのメッセージを一部日本語にしました。UTF-8で保存します。

```ts:extension.ts
import * as vscode from 'vscode';

export function activate(context: vscode.ExtensionContext) {

	console.log('おめでとうございます！,あなたのエクステンション"evaextension"は現在アクティブです！');

	const disposable = vscode.commands.registerCommand('evaextension.helloWorld', () => {
		vscode.window.showInformationMessage('Hello World! evaExtensionです！');
	});

	context.subscriptions.push(disposable);
}

export function deactivate() {}
```

# VSCodeを起動
evaextensionフォルダをカレントにしてVSCodeを起動します。

```cmd:
C:\developments\vscode\evaextension>code .
```
VSCodeが起動します。既定でできたなりのlaunch.jsonの設定で、デバッグ実行開始してみます。このとき、const disposable = vscode.commands.registerCommandの行がブレークするようにしておきます。

もうひとつのVSCodeが起動して、検索欄に「拡張機能開発ホスト」と表示されています。

![vscodeextension3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118036/fd52598a-725d-5ff2-1535-1760becfb266.png)

「拡張機能開発ホスト」の方のVSCodeでコマンドパレットを開きます。

筆写の環境では既に実行していますので、下図のように「Hello World」コマンドが候補に現れますが、初回の場合はコマンドパレットのプロンプトに「Hello World」します。候補が出ている場合は選択します。

![vscodeextension4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118036/cf6e712e-e26c-c7aa-7307-68c1d7072ffb.png)

無事にブレークしました。コンソールログ出力は実行されていますので、デバッグコンソールに日本語メッセージが出力されています。

![vscodeextension5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118036/378c6b40-11d9-866b-2180-719f62fa71b3.png)

ここでステップオーバーするとコードの最後まで走行し、「拡張機能開発ホスト」の方のVSCodeで下図の（ウィンドウ右下の）メッセージが表示された実行成功です。

![vscodeextension6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118036/84db5299-09b1-6907-203c-f106a32e70fd.png)

次回はいよいよextension.tsになにかサンプル実装してデバッグ実行してみます。（前回も言ってなかったか？）

# おわりに
いかがでしたでしょうか？なにかの参考になれば幸いです。とりあえずデバッグできる環境が整ったので、はやく「拡張機能開発ホスト」の方が読み込んだテキストに対してあれこれやってみたいです。
Crate CTF Writeup

# はじめに

今回はsknbでcrate ctfに参加してきました。
夜の10時から朝6時という大会時間で、かつ言語はスウェーデンなので、いつもと違う環境でのCTFでした。
結果としては148位でした。
Webの問題で解けそうな問題を2つ落としてしまったのが悔しかったです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3510659/02e1fef2-f908-7b79-dcf0-6e2ad5e0693b.png)

# KaKlickare

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3510659/ef6105ae-f86d-c2a4-ec51-9f75ebc9f46e.png)
ホームページに行くとGet the flag!と書かれたボタンが出るので
それを押すと、1000000000回クリックしろと言われます。
リクエストを見ると、Cookieヘッダのclicksの値で判定しているので
clicksを以下のコードで改ざんし、リクエストを送信することでフラグが手に入ります。
```javascript
(async () => {
  const baseUrl = "http://challs.crate.nu:50012/";
  const clickCnt = "1000000000";
  const res = await fetch(baseUrl + "flag.php", {
    method: "POST",
    headers: {"Cookie": `clicks=${btoa(clickCnt)}`}
  });
  console.log(await res.text());
})();
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3510659/7a58492a-ad30-6d63-80c8-8368bc86f17c.png)

# XML-kontroll

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3510659/89fafeb1-9ab5-7d2b-5947-7d3a2c981552.png)

XMLを入力するページが出てきます。
ここですぐにXXEを思いつきました。
XMLには実体という変数のような機能があります。
実体を定義するとXML中にそれを```&実体名```で記述すると
実体の内容を参照することができます。
外部実態参照(XXE)とは実体の内容に外部のデータを使用できるというものです。
例えばローカルファイルもそれに含まれます。
以下の実態を用いて/etc/passwdの内容を取得したところ、ユーザ名にフラグが書いてありました。
```
<!DOCTYPE foo [<!ENTITY example SYSTEM "/etc/passwd"> ]><data>&example;</data>
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3510659/361b40a4-113d-50e4-5868-c55ff2f59ea1.png)

# おわりに

私が大会中はこの2つを解きました。
この他に3つWeb問がありましたが、その2つは自分の知っていた脆弱性だったので
解けなかったのが悔しかったです。
次はSeccon Qualsなので気合入れていきます。
Nginxプロセスの「IO read count」とは？増減から推察できること

**Nginxプロセスの「IO read count」**は、通常、Nginxプロセスがディスクやファイルシステムから読み取った回数を示すメトリックを指します。この情報は、Linux環境で`/proc/[pid]/io`や`iostat`、監視ツール（例えば`pidstat`や`collectd`）を使って取得できる場合があります。

### IO read countの意味

1. **定義**
   IO read countは、Nginxが以下のような操作を行う際にカウントが増加します：
   - 静的ファイル（HTML、画像、CSSなど）をディスクから読み取る。
   - 設定ファイルを再読み込みする。
   - キャッシュされたファイルを読み取る。
2. **単位**
   - この値は、システムコール（`read()`など）をカウントしている場合が一般的です。
   - 必ずしも読み取ったデータ量ではなく、**読み取りの回数**を示します。

---

### この数値の増減から推察できること

IO read countの増減は、Nginxの動作やシステムの状態を理解するために役立ちます。

#### **1. 数値が多い場合**

- **高トラフィック**
  静的ファイルやキャッシュからの読み取りが頻繁に行われている可能性があります。特に、画像やJavaScriptなどのリソースを多くのクライアントが要求している場合。
- **キャッシュが機能していない**
  ファイルが毎回ディスクから読み取られている場合、キャッシュの設定が適切でないか、キャッシュのヒット率が低い可能性があります。
- **リソースの不足**
  メモリ不足により、Nginxが頻繁にディスクI/Oに依存している可能性があります。

#### **2. 数値が少ない場合**

- **低トラフィック**
  サーバーへのリクエストが少ない。
- **キャッシュが機能している**
  メモリキャッシュや他の高速キャッシュ（例：Redis、Memcached）が有効に機能している可能性があります。
- **リクエスト内容の変化**
  ディスクI/Oを伴わないAPIリクエストなどが主流になっている場合。

---

### IO read countを活用する場面

1. **パフォーマンスチューニング**
   - キャッシュ設定を見直し、不要なディスクI/Oを削減する。
   - キャッシュレイヤー（`proxy_cache`や`fastcgi_cache`）のヒット率を上げる。
2. **問題の特定**
   - 高いIO read countが持続する場合、ディスク性能のボトルネックや、過剰なリクエスト負荷を疑う。
   - 突然の増加は、DoS攻撃やキャッシュのクリアなどの影響を示唆する可能性。
3. **リソースの最適化**
   - メモリ割り当てを増やすことで、キャッシュを強化し、IO read countを減らす。
   - 静的ファイルの読み取りを減らすために、CDNを利用する。

---

結論として、Nginxの「IO read count」はサーバーのワークロードやディスクI/Oの負荷を示す重要な指標です。これを監視することで、パフォーマンスのボトルネックやリソースの使い方を最適化できます。
[Flutter] MapBoxからMapLibreに移行した理由

![スクリーンショット 2024-11-18 22.51.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/3be3e75f-2caf-4244-fc0f-868dd49df8a4.png)



## 初めに

実はもっと前にこの記事を書きたかったのですが、私が適応障害になってしまい、それどころではありませんでした💦 治ったり、再発したりと大変でしたが、なんとか落ち着きました。
「ふと書きたいな〜〜」と思ったため書き始めました。

こちらの記事はFlutterKaigi2024のプロポーザルで落選してしまったを記事にして投稿予定です。少しずつ書いていきますね。


# MapBoxとは
- Mapboxは、様々な情報を集約し自由自在な地図描画を行うことでロケーションデータの活用を推進する地図開発プラットフォーム
- アプリごとに地図のデザインをカスタマイズできる

https://www.mapbox.jp/

## FlutterにおけるMapboxについて
- FlutterにおいてもMapboxを使うことができる
    - マップのデザインにおいてもカスタマイズできる

https://docs.mapbox.com/ja/flutter/maps/guides/

### Packagesについて

#### mapbox_maps_flutter

https://pub.dev/packages/mapbox_maps_flutter

- Mapboxが公式に開発したPackages
- 1.0が公開されたのは８ヶ月ほど前なので最近できたものになりますね
    - 使い方などの記事は以前書いた記事を載せておきます

https://qiita.com/isekiryu/items/4297663d45e33c19cc4f

#### mapbox_gl

https://pub.dev/packages/mapbox_gl

- このPackagesはコミュニティ主導で作られたもの
- 昔から使われていたPackages
- 記事が多めにあるため、実装する上で手助けになることが多い



# MapLibreとは
- MapLibreは、オープンソースの地図ライブラリで、インタラクティブな地図を作成するためのツールを提供している


https://maplibre.org/

- Flutterにおいても使用が可能
    - 私は以下のPackagesを使用し、開発をしました。

https://pub.dev/packages/maplibre_gl

:::note info
実装については、別の記事で書こうと思います。ぜひお楽しみにぃぃ
:::


# 本題

## MapBoxからMapLibreに移行した理由

ある日、アプリ開発をしていたときに、僕の身内の一人が一言アドバイスをくれた。

<b>「Map系のアプリは急にユーザー数が増えることがあって、その影響で多額の使用料がかかるから気をつけたほうがいい」</b>

なるほど、と思いつつ、MapBoxの使用料を確認してみたところ、ユーザ数が少ない割にマップの表示回数が増えていた。まだまだこれから宣伝だったり、アプリの改善とかをして使ってもらおうと思った矢先だったので結構危なかった。

しかしどうしてもマップを使いたかったため悩んでいたところ、神的なアドバイスをしてくれた。

<b>「MapLibreを使えばいいよ」</b>

MapBox位の完成度になるのかなあと結構不安になっていましたが、いざ触ってみるとしっかりとマップとして機能が果たしているだけでなく、自分の理想としているマップのスタイルに近づけることができた気がした。

結果的にマップについては、ほぼ満足のいく形で実装することができた。

しかし、課題点としては、まだまだ技術記事が少ないため、実装が困難だったり、issuesなどで質問する必要があった。

今後としては実装してきたことについて記事にしていきたいと思う。

今回はここまでにして、次以降から実際に技術的な実装をメインで書いていきます。


# まとめ
- Map系のアプリは知らない間にアクセスが増えていることが多い
- その結果、使用料が高くなってしまうことがあるらしい
- MapLibreを使用すると、そういった心配がなくなるらしい


# 最後に
MapLibreを使用したアプリを個人で開発しています･:*+.\(( °ω° ))/.:+

![Group 93.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/318bb611-4e87-6c02-6a2c-2c5bb93c392a.png)



https://apps.apple.com/jp/app/foodgram/id6474065183


- 「FoodGram」は、フードシェアアプリとなっており、あなたの好きなレストランの食事をぜひこのアプリで共有していただけると嬉しいです!!

<b>このアプリのセールスポイント
- このアプリだけのレストランマップをユーザー全員で作成できる⭐️


例）
<img width="30%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/ea32b057-1626-f371-cdc0-45bcffc8ff6b.jpeg">


ぜひダウンロードして使ってくれると嬉しいです🙇
基本情報技術者　試験学習のアウトプット

# テクノロジ系　基礎理論①
コンピュータの基礎理論（データの単位や数値の数え方）を学習する。
## ビットとバイト　（データの単位）
これらの知識が直接問題として出題されることはないが、テクノロジ系の前提知識としてさまざまなところに登場するためしっかりと理解しておくこと。
###### ビット
コンピューターが扱うデータの最小単位。１ビットは"0 or 1"で表す。
###### バイト
8個のビットの集まり。１ビットは"0 or 1"なので１バイトは2の8乗（256通り）表すことができる。
基本情報技術者試験では0と1に並びで表わされた数値のことを「ビット列」もしくは「ビットパターン」と呼ぶ。ex) 10010011
###### さまざまなデータの単位
コンピュータの世界では、非常に大きな値や、非常に小さな数値を扱うことがあるため、データを簡潔に表すための単位が存在する。
| 単位    | 記号 | 10進数表記           |　累乗 　|
|:------:|:---:|:-------------------:| :----: |
| テラ    | T   | 1,000,000,,000,000  | 10^12  |
| ギガ    | G   | 1,000,000,000       | 10^9   |
| メガ    | M   | 1,000,000           | 10^6   |
| キロ    | K   | 1,000               | 10^3   |
| 基準    |     | 1                   | 1      |
| ミリ    | m   | 0.001               | 10^-3  |
| マイクロ | μ   | 0.000001            | 10^-6  |
| ナノ    | n   | 0.000000001         | 10^-9  |
| ピコ    | p   | 0.000000000001      | 10^-12 |

スマホの通信量表記である1GBはバイトに直すと１０億バイトになり、ビットに直すと８０億ビットとなる。
## 数値の数え方
###### 10進数
値が10になる時、桁が一つ上がる表記法。人が日常的に使っている表記法。
ex) 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19...
###### 2進数
値が2になる時、桁が上がる表記法。コンピュータの世界でよく使われている表記法
ex) 0 1 10 11 100 101 110 111 1000 1001 1010...

:::note
10進数では「10 = じゅう」と読むが、2進数では「10 = いちぜろ」と読む。
ただし表記は同じなため、何進数表記なのかを記載する。2進数 = (10)2　10進数 ＝ (10)10と表記される
:::

###### 16進数
値が16になる時、桁が上がる表記法。10進数・2進数の他に、コンピュータでよく使われている表記法。
ex) 0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14...
普段使用しているアラビア数字には0~9までの10種類の数字記号が存在するため、10~15はアルファベットを使用している。そのため、10 = A, 15 = F　となる。
## 小数
###### 整数部と小数部
小数点を境に２つの部分に分けることができる。小数点より左側を「整数部」、右側を「小数部」と呼ぶ。
なお、2進数の小数は２進小数・16進数の小数は１６進小数と呼ぶ。
###### 有限小数
小数部の桁数に限りがある小数のこと。
ex) 0.5, 1.1　など
###### 無限小数
小数部の桁数に限りがない小数点のこと。
ex) 円周率　など
###### 循環小数
無限小数で、ある桁から同じ数字の列が無限に繰り返される小数のこと。
ex) 1 / 7 = 0.142857142857142857...... 小数第1位から142857が無限に繰り返される
## 基数変換と桁の重み
###### 基数
桁上がりの基準となる数。10進数では10。2進数では2。16進数では16。
どの表記法であっても、表記が異なるだけで本質的には同じ値を表している。
| 2進数  | 10進数 | 16進数 |
|:-----:|:-----:|:------:|
| 0     | 0     | 0      | 
| 1     | 1     | 1      |
| 10    | 2     | 2      | 
| 11    | 3     | 3      | 
| 100   | 4     | 4      |
| 101   | 5     | 5      |
| 110   | 6     | 6      |
| 111   | 7     | 7      | 
| 1000  | 8     | 8      | 
| 1001  | 9     | 9      | 
| 1010  | 10    | A      | 
| 1011  | 11    | B      | 
| 1100  | 12    | C      | 
| 1101  | 13    | D      | 
| 1110  | 14    | E      | 
| 1111  | 15    | F      | 
| 10000 | 16    | 10     | 

###### 桁の重み
位のこと。10進数では小数点の左から一の位、十の位、百の位…と呼ぶ。
例えば、「7297」の千の位と一の位は同じ「7」だが、千の位は一の位より千倍大きい。（桁ごとに重みが異なるため）
数の大きさは桁ごとの重みをかけた上で、それらを合計することで表現されている。
###### 指数
桁の重みは、数が大きくなればなるほど桁数が多くなるため、読みづらくなる。この問題を解決するために指数が存在する。
ex) 1000 = 10 * 10 * 10 = 10^3　と表記される。

:::note
指数が[0]の場合、基数の値にかかわらず計算結果はすべて1になる。
指数が負の場合は例えば2^-3であれば 1 /2^3 となる。
:::

###### 2進数の桁の重みと10進数への基数変換
ex) 1001.001

| 数字    | 1    | 0   | 0   | 1  | .  | 0   | 0    | 1     |
|:-------:|:---:|:---:|:---:|:---:|:-:|:---:|:----:|:------:|
| 桁の重み | 2^3 | 2^2 | 2^1 | 2^0 |   | 2^-1 | 2^-2 |  2^-3 |

各桁の重みをかけて各桁の積を合計することで2進数を10進数で表現できる。
2進数[1001.001] = 1 * 2^3 + 0 * 2^2 + 0 *2^1 + 1 * 2^0 + 0 * 2^-1 + 0 * 2^-2 + 1 * 2^-3 = 8 + 0 + 0 + 1 + 0 + 0 + 1 / 8 =9.125 ←10進数での表記。

## 終わりに
参考資料：いちばんやさしい 基本情報技術者 絶対合格の教科書＋出る順問題集
PostgreSQL + pgvector を Docker Compose で手軽に試す方法

PostgreSQL の Docker イメージを使い、docker-compose を用いて pgvector の有効化と初期データの投入を簡単にセットアップできるコードを作成しました。

既存の記事では、pgvector の有効化や初期データ投入をコンテナ起動時に自動実行する方法（docker-entrypoint-initdb.d を活用する設定）まで紹介した記事が見当たらなかったのでこの投稿に至ります。

この構成では、PostgreSQL に pgvector をインストールし、初期化スクリプトを自動実行させる設定が含まれています。以下にコードの一部を抜粋します。

docker-compose.yml と Dockerfile を組み合わせ、pgvector のインストールとセットアップを行います。

```yaml
# docker-compose.yml
version: "3.9"
services:
  postgres:
    build:
      context: .
    ports:
      - "5432:5432"
    volumes:
      - ./postgres:/var/lib/postgresql/data
      - ./postgres/init:/docker-entrypoint-initdb.d
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
      - PGDATA=/var/lib/postgresql/data/pgdata
```

```Dockerfile
# Dockerfile
FROM --platform=arm64 postgres:17.1

RUN apt-get update && \
    apt-get install -y git make gcc postgresql-server-dev-17

RUN cd /tmp && \
    git clone --branch v0.5.1 https://github.com/pgvector/pgvector.git && \
    cd pgvector && \
    make && \
    make install && \
    cd ../ && rm -rf pgvector

```

詳細なコードと手順については、GitHub リポジトリにまとめています。

[👉 GitHub リポジトリはこちら](https://github.com/yolo-kiyoshi/pgvector-sample/tree/master)

## 参考
- https://note.com/sho7650/n/n7f3a03309788
プリンシパルが持つパーミッションを一覧で出力する

## 概要
Google Cloudで特定のプリンシパル（ユーザーやサービスアカウントなど）が持つパーミッションを確認する際、「割り当てられているロールを抽出」し、その後「各ロールに含まれるパーミッションを抽出する」という手順を踏むのは手間がかかります。
そこで、これらを一括して一覧で出力できるスクリプトを作りました。

## コード

gcloud CLIがインストールされている環境で以下のコードを実行します。
`PROJECT_ID`と`PRINCIPAL_EMAIL`は任意の文字列をいれてください。

```shell
#!/bin/bash

# 設定：プロジェクトIDとプリンシパルのメールアドレス
PROJECT_ID="your-project-id"  # プロジェクトIDを入力
PRINCIPAL_EMAIL="your-principal-email@example.com"  # プリンシパルのメールアドレスを入力
OUTPUT_FILE="permissions_output.txt"  # 出力ファイル名

# 出力ファイルを初期化
> $OUTPUT_FILE  # 中身を空にする

# 1. プリンシパルに割り当てられているすべてのロールを取得
roles=$(gcloud projects get-iam-policy $PROJECT_ID \
    --flatten="bindings[].members" \
    --format="value(bindings.role)" \
    --filter="bindings.members:$PRINCIPAL_EMAIL")

# 2. 各ロールに含まれるパーミッションを取得し、重複を排除してファイルに出力
for role in $roles; do
    gcloud iam roles describe $role --format="value(includedPermissions)" | tr ',;' '\n' >> $OUTPUT_FILE
done

# 結果を一意にする（重複排除）
sort $OUTPUT_FILE | uniq > "unique_$OUTPUT_FILE"

# 出力結果の案内
echo "すべてのパーミッションを 'unique_$OUTPUT_FILE' に出力しました。"

```

Cloud Shellで実行すると、Cloud Shell エディタ上でファイルを生成されたファイルを確認することができます。

![スクリーンショット 2024-11-18 17.11.26（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147689/b4f77432-6bdc-dc43-620e-940d45fca249.png)

以上です。

## 参考リンク

https://cloud.google.com/sdk/gcloud/reference/projects/get-iam-policy

https://cloud.google.com/sdk/gcloud/reference/iam/roles/describe