OmniAICreator/Qiita-1.07M huggingface dataset:
Node.jsランタイムでSJISのcsvファイルを出力するLambda

# 一覧データをcsv出力
データベースにはUTF-8で保管されているものの、
「ファイルの文字コードは **Shift-JIS** で（Excelでそのまま開きたいから）」
という要件があったとします。

今回は **AWS Lambda(Node.jsランタイム)** で構築したアプリケーションだったので、その例です。

ポイントは以下2点です。
1. UTF-8からShift-JISへのエンコード
1. Lambdaペイロード制限を考慮してS3署名付きURLを利用

## まずはcsvデータを生成
csv形式へのパースには[Papa Parse](https://www.papaparse.com/)を、エンコードには[encoding.js](https://github.com/polygonplanet/encoding.js)を使うことにしました。
```npm install```しておきます。

DBから取得したデータ配列を渡して、csv形式＆SJISエンコードした文字列を返す処理です。
```javascript
const Papa = require('papaparse')
const encoding = require('encoding-japanese')

// CSV変換
const transformToCSV = (dataList) => {
  const config = {
    quotes: true, // 値をクォーテーションで囲む
    quoteChar: '"', // クォーテーション文字
    delimiter: ',', // 区切り文字
    newline: '\r\n', // 改行文字
    header: true // キーをヘッダーとして扱う
  }
  // CSV形式に変換
  const delimiterString = Papa.unparse(dataList, config)

  // 文字コード変換
  const strArray = encoding.stringToCode(delimiterString)
  const convertedArray = encoding.convert(strArray, 'SJIS', 'UNICODE')
  const uintArray = new Uint8Array(convertedArray)

  return uintArray
}
```
（参考ページ）

https://qiita.com/kenji123/items/cad6dad1476555ac0166

こちらの例のように、そのままレスポンスを返してフロントではBlobリンクを生成してダウンロードさせればよいのですが、ここで第2のチェックポイントです。

## Lambdaでは6MBを超えるレスポンスは返せない
> [ERROR] [************] LAMBDA_RUNTIME Failed to post handler success response. Http response code: 413.

このようなエラーが発生していたらこの制限にかかっているようです。

https://qiita.com/shibadai/items/fd483ccd2ad8c8d89c1a

DBから取得した出力用データがこれを超えてしまう場合はどうするか？
→ **S3** に転送して、**署名付きURL** を発行するのがよさそうです。
　以下の記事が参考になります。

https://dev.classmethod.jp/articles/lambda-over-6mb-response-use-s3-pre-signed-url/

先ほどのエンコード済みcsvデータをS3に転送して署名付きURLを取得する処理です。
AWS接続情報やバケット名などは```config```で別途管理しているものとします。

```javascript
const { getSignedUrl } = require('@aws-sdk/s3-request-presigner');
const {
  GetObjectCommand,
  S3
} = require('@aws-sdk/client-s3');

// DL用URL取得
const getDownloadLink = async (csvData) => {
    // S3準備
    const s3 = new S3({
      credentials: {
        accessKeyId: config.aws.accessKeyId,
        secretAccessKey: config.aws.secretAccessKey
      },
      region: config.aws.region
    })

    // パス・ファイル名は任意
    const filename = 'sample_sjis.csv'
    const path = 'download/' + filename

    // S3にファイル転送
    const params = {
      Bucket: config.aws.bucket,
      Key: path,
      Body: csvData
     };
     await s3.putObject(params, function(err) {
      if (err) {
        throw new Error()
      }
     })

    // 署名付きURL取得
    const downloadUrl = await getSignedUrl(s3, new GetObjectCommand({
      Bucket: config.aws.bucket,
      Key: path,
      ResponseContentDisposition: 'attachment; filename="' + encodeURIComponent(filename) +'"'
    }), {
      expiresIn: 60 * 10
    })

  return downloadUrl
}
```

これをレスポンスとして返して、フロント側でURLにアクセスすればダウンロードが開始されます。

**Lambda関数のメモリ設定** も必要に応じてご確認ください。

# 脚注
- 24/8/27
aws-sdk の箇所を **v2** から **v3** 準拠に更新しました。

https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/migrating.html
Git GitHubの最低限の使い方

# はじめに
GitとGitHubについて、本当に最低限の使い方について学んだので、その備忘録です。

# Git
Gitは、テキストファイルなどのバージョンを管理するためのソフトウェア(インストール方法は省略)。リモートリポジトリとそのコピーのローカルリポジトリがある
#### ローカルリポジトリの作成
1. ローカルにディレクトリを作る
1. その中で`$ git init`
#### リモートリポジトリへのアップロード
`$ git push origin main` (mainはブランチの名前)
#### リモートリポジトリの最新の状態をローカルリポジトリにダウンロードして反映する
- `$ git pull`
- `pull` = `fetch` + `merge` とのこと
#### 変更したファイルを元に戻す
`$ git checkout .`
#### コミットログを見る（下記は５つ前まで）
`$ git log -5`
#### 現在のブランチの状態を確かめる
`$ git status`
#### ブランチ一覧確認
`$ git branch`
#### originの確認
- `$ git remote get-url origin`
- **origin**は、リモートリポジトリのURLの別名
#### コミット
1. ファイル編集
1. コミット直前のエリア（ステージングエリア）に追加
`$ git add .` (この場合、変更したもの全て)
1. ローカルリポジトリにコミット
`$ git commit -m "コミットメッセージ"`

# GitHub
自分のコードを公開する場所
1. アカウントを作成
1. リモートリポジトリを作成する。そのURIを使う
1. インデックスをGitHubに作成
`$ git remote add origin URI`
1. ローカルリポジトリからpushする
【React】学習記録アプリを改良してみた

# はじめに
以前制作しました学習記録アプリを改良してみました。
制作して感じたことなどをまとめてみました。

↓前回の記事はこちらです

https://qiita.com/masafumi1073/items/b3bf7997c252bde7482b

# 制作したアプリ
前回と機能的な面では大きな違いはありません。
今回は以下の3つを新規で追加しています。
+ Supabaseを使用した学習記録のデータの管理
+ Github ActionsによるCICDの追加
+ Jestとreact-testing-libraryを使用したテストの実装

![2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3835217/4680e26d-73ec-e104-c6fa-ff737af129a9.gif)

# 工夫した点
前回はスタイリングを行わず、機能面の実装だけにとどめていたので、今回はスタイリングを行いました。また、styled-componentsを初めて使ってみました。普段はTailwind CSSを使用していますが、クラスが多くなりごちゃごちゃするのが好きではないため、styled-componentsを試してみました。

https://styled-components.com/

# 大変だったところ
***全てです...***
冗談ではなく、実際すべての作業が初めてだったため、かなり苦戦しました。特にテストコードの実装に苦労しました。

+ どのようなコードを書けばテストが行えるのか？
+ テストの要件を満たすにはどのようなことをテストすれば良いのか?

上記のようなことが全く分からず***絶望しかけてました***。

今回はとにかく公式のドキュメントを読みまくりました。エラーを解決したいのならQiitaの記事やChatGPTに聞くのも良いと思います。ただ、今回の場合はそもそも何をすればよいのかわかっていないので公式のドキュメントを読み込みました。教材で扱うレベルのことであるならば絶対載っていると思ったからです。結果としてしっかりとテストコードを実装することができたの正解だったと思いました。

# 良かったこと
テストの実装でつまづいたことは前述の通りです。その過程で私は公式ドキュメントを読みましたが、そこで良かったことは***公式ドキュメントを読む力***がついたことです。

ドキュメントは英語が多くてどうしても読むのが苦手でした。ただ一番正確なことが書いてあるのは、公式ドキュメントなので読めるようになって良かったです。

# 最後に
Reactでアプリを作り始めてから1ヶ月が経過しました。今まで全く触れたことがなかったことを、たった1ヶ月でできるようになっていて本当に驚いています。

正直、今回はテストのところで***5回ぐらい心が折れました***。ただ、その日分からなくても、次の日にやると意外とできたりするのです。

そんなこんなで改良版の学習記録アプリが完成しました。



# JISOUのメンバー募集中
プログラミングコーチングJISOUではメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか？

気になる方はぜひHPからライン登録お願いします👇

https://projisou.jp
Qiitaに動画を載せたいときに使うツール

# 結論
https://ezgif.com/video-to-gif

このサイトで、撮影した動画をgifに変換することができるので、変換したgifをコンピュータ内に保存して、保存した内容をQiitaにドラッグ&ドロップすることで撮影した動画を載せることができます。

これ以外にいい方法があればコメントお願いします。
[Android その１] Androidの基礎 


# この記事について
Androidアプリケーション開発について興味があるので、調べつつ、アウトプットとして記載をしたいと思います。
特に、__4. アプリケーションの基本要素__ について記載を進めていこうと思います。
また言語はJavaで書いていこうと思います。ですが、後々にKotlinでの記載も進めていきます。

# Androidについて
Androidは、Googleが開発したオープンソースのモバイルオペレーションシステムです。主にスマートフォンやタブレットで使われており、世界中で非常に広く普及しています。

##  1\. Androidの構成
Android システムは主に以下のコンポーネントで構成されています：
* __Linux カーネル__: Android の基礎は Linux カーネルで、メモリ管理、プロセス管理、ネットワークプロトコルスタックなどの基本的なシステム機能を提供します。
* __ハードウェア抽象化レイヤー (HAL)__: ハードウェアと上位層のソフトウェア間のインターフェースを提供し、Android がさまざまなハードウェアに対応できるようにします。
* __Android ランタイム (ART)__: Java バイトコードをネイティブコードに変換し、アプリの実行を効率化します。ART は、以前の Dalvik 仮想マシンに代わるもので、パフォーマンスの向上とアプリの実行速度を改善します。  
* __ライブラリ__: Android はさまざまな C/C++ ライブラリを使用しており、これらはアプリケーションフレームワークに機能を提供します。たとえば、WebKit (ブラウザエンジン)、OpenGL (グラフィックスエンジン)、SSL (セキュリティ) などです。
* __アプリケーションフレームワーク__ : 開発者がアプリを作成するための API とサービスを提供するレイヤーです。このフレームワークには、アクティビティマネージャ、リソースマネージャ、通知マネージャなどがあります。
アプリケーション: Android デバイスには、プリインストールされたアプリケーション (例: 電話、メール、ブラウザなど) と、ユーザーが Google Play ストアからダウンロードしたアプリケーションが含まれます。

##  2\. Androidのアーキテクチャ
Androidのアーキテクチャは、主に次の４つのレイヤーで構成されています：

1\. Linux カーネル: ハードウェア抽象化と基本的なシステムサービスを提供する。
2\. ライブラリ & Android ランタイム: コアライブラリと ART を含み、アプリの実行環境を提供する。
3\. アプリケーションフレームワーク: 開発者が利用できる API やサービスを提供する。
4\. アプリケーション: ユーザーがインターフェースとして直接使用するアプリケーション。

## 3. 開発環境
Android アプリの開発には、主に以下のツールが使用されます：

* Android Studio: Google が公式に提供する統合開発環境 (IDE) で、アプリの設計、開発、デバッグ、テストを行うための機能が備わっています。
* Java または Kotlin: Android アプリは主に Java または Kotlin 言語で書かれています。Kotlin は Google によって公式にサポートされる言語で、Java に代わるモダンなオプションとして人気があります。
* Android SDK: アプリの開発に必要なライブラリ、ツール、およびサンプルコードを含むソフトウェア開発キットです。

## 4. アプリケーションの基本要素
Android アプリは以下の主要なコンポーネントで構成されています：

* アクティビティ (Activity): ユーザーインターフェースを構成する単一の画面。各アクティビティは、独自のライフサイクルを持ち、アプリの異なる部分を表現します。
* サービス (Service): バックグラウンドで動作するコンポーネントで、ユーザーインターフェースを提供せず、長時間実行される処理を行います。
* コンテントプロバイダ (Content Provider): アプリ間でデータを共有するためのメカニズムを提供します。
* ブロードキャストレシーバ (Broadcast Receiver): システム全体で送信されるイベントをリッスンし、他のコンポーネントに通知を送るために使用されます。

## 5. アプリのパブリッシングと配布
Android アプリは、通常、Google Play ストアを通じて配布されます。開発者はアプリをビルドし、テストした後、Google Play デベロッパーアカウントを使用してアプリを公開します。また、APK ファイルを直接提供する方法もありますが、セキュリティと信頼性の観点から Google Play を通じて配布することが推奨されます。
HTML: file読み込みで疑似loop

以下の例ではfileを読み込んだ直後からa要素にloop回数を表示しています。これだけでは当然何の意味も無い処理です
```html
<input type=file oninput="files[0].arrayBuffer().then(b=>oninput(++a.innerHTML))"><a id=a>
```
応用すると下らないanimationを表示したり、gameを作ったり…できるかな? あえてこんな方法にする必要ないだろうと突っ込みたくなりますが…。
【c++】ABC368 A-C問題解説【ACコード付き】

# AtCoder Beginner Contest 368
A,B,Cの3完。

レートは876→859の-17となり2週連続レートダウン。

5回ほど前のABCで過去最高の898を記録してから、850から900の間を行ったり来たりしている。

やはり何も対策しなかったらレートが落ちるのは当然だし、一度停滞期が来たからと言って諦めたくない。

今年中の青色へは毎回+50を記録しないといけないので相当気合を入れないといけないが、ちゃんと精進していけばレートが上がっていく余地はまだまだ感じるので、言い訳せずに時間を確保して精進するのみ。

https://atcoder.jp/contests/abc368

## A - Cut
昇順に並んでいる $N$ 枚からなるカードの山札を、山の下から $K$ 枚を取り出して、その順番を保ったまま上に重ねた時、上からどのような番号で並んだ状態になるか出力せよ、という問題。

まず $N - K$番から$N$番までのカードを出力し、その後$1$番から$N - K - 1$番までのカードを出力すればよい。

```cpp
ll N,K;
ll A[1000009];

int main()
{
	cin >> N >> K;
	for (int i = 0; i < N; i++) cin >> A[i];
	for (int i = N - K ; i < N; i++)
	{
		if (i != N - K) cout << " ";
		cout << A[i];
	}
	for (int i = 0; i < N - K; i++) cout << " " << A[i];
	cout << endl;
	return 0;
}
```

## B - Decrease 2 max elements
長さ$N$の正整数列が与えられるので、降順にして前二つの要素を1引く操作を繰り返して、要素が0でないものが1つ以下になるまでの操作回数を求めよ。

ひたすら該当の操作を繰り返す素直な実装にし、降順に並び替えた時の $A[1]$ 、つまり2つ目に大きな要素が0になったら終了するようにする。

```cpp
ll N;
vector<ll> A(1000009);

int main()
{
	cin >> N;
	for (int i = 0; i < N; i++) cin >> A[i];
	ll count = 0;
	while (1)
	{
		sort(A.begin(), A.begin() + N);
		reverse(A.begin(), A.begin() + N);
		if (A[1] == 0) break;
		A[0]--;
		A[1]--;
		count++;
	}
	cout << count << endl;
	return 0;
}
```

## C - Triple Attack
$N$体の敵がいて、それぞれの体力が $A_i$ である。
0でカウントを始め、カウントが3の倍数の時には3ダメージを与え、そうでない時には1ダメージを与える。前の敵から体力が0以下になるように攻撃をする時、最終的なカウントはいくつになるか、という問題。

最初はひたすら該当の操作を繰り返す実装にしていたが、TLEしたので3回の攻撃を1セットと認識し、3回の攻撃の総和である5で何回攻撃できるかを計算するように計算量を改善した。

```cpp
ll N;
ll A[1000009];

int main()
{
	cin >> N;
	vector<pair<ll, ll>> enemy(N);
	for (int i = 0; i < N; i++) cin >> A[i];
	ll T = 0;
	ll num = 0;
	while (num < N)
	{
		ll tmp = A[num] / 5;
		A[num] = A[num] % 5;
		T += tmp * 3;
		while (A[num] > 0)
		{
			T++;
			if (T % 3 == 0) A[num] -= 3;
			else A[num]--;
		}
		num++;
	}
	cout << T << endl;
	return 0;
	
}
```

## D - Minimum Steiner Tree
公式解説のpythonを見てcppで実装したコード。

考え方をわかりやすく説明すると、Union-Findのような木構造を思い浮かべたときに、葉（木構造の末端、それ以上下位の階層の分岐が存在しない）が条件を満たす頂点でなければ削除してさらに上位階層（親ノード）をチェックする、条件を満たす頂点だった場合はそれ以上上の階層は残す、という操作を繰り返す。それらを下記のプログラムでは幅優先探索で実装している。

```cpp
int main() {
    int N, K;
    cin >> N >> K;

    vector<set<int>> edge(N);

    for (int i = 0; i < N - 1; ++i) {
        int a, b;
        cin >> a >> b;
        a--; // 0-indexed に変換
        b--; // 0-indexed に変換
        edge[a].insert(b);
        edge[b].insert(a);
    }

    set<int> V;
    for (int i = 0; i < K; ++i) {
        int v;
        cin >> v;
        V.insert(v - 1); // 0-indexed に変換
    }

    vector<int> deg(N);
    for (int i = 0; i < N; ++i) {
        deg[i] = edge[i].size();
    }

    queue<int> q;
    for (int i = 0; i < N; ++i) {
        if (deg[i] == 1) {
            q.push(i);
        }
    }

    int ans = N;
    while (!q.empty()) {
        int v = q.front();
        q.pop();
        if (V.find(v) != V.end()) continue;

        int vv = *edge[v].begin();
        edge[vv].erase(v);
        ans--;

        if (edge[vv].size() == 1) {
            q.push(vv);
        }
    }

    cout << ans << endl;

    return 0;
}

```
LangChain入門その1 ~全体像~

LangChainはLLMアプリケーションの作成を加速するためのフレームワークです。現在、OpenAIをはじめ多くの企業がLLM利用のためのAPIを公開していますが、各APIの入出力のフォーマットはバラバラであるためPoC時にLLM同士を比較したり、LLM変更の際のコストが大きくなってしまいます。LangChainでは各LLM APIのフォーマットを統一してくれており、モデルの変更や比較が非常に高速にできます。また、LLMアプリケーションを実装する上で有用なRAGやプロンプト管理、agentなどの機能が豊富に揃っており、即座にLLMアプリケーションを作成することができます。LangChainの主な機能としては次のようなものが挙げられます。
1. Model I/O
2. Retrieval
3. Chains
4. Agent Tooling

これら機能について簡単に解説していきます。

## Model I/O

OpenAI以外にもmicrosoft Azure, AWS, Google, Anthropicなどさまざまな企業がLLM APIを提供しています。先に述べたようにLangChainではこれらAPIの差異を吸収し、統一したインターフェースで各LLMを利用することができます。

ビジネスシーンで精度を求めるのであれば、Azureが提供しているOpenAIのGpt-4o, Googleが提供しているGemini 1.5 pro, AWSが提供しているAnthropicのClaude 3.5 Sonnetの3つを比較することが多いと思いますが、これらを比較しようと思ったら各サービスのAPIの把握、プロンプト入力形式変換のフォーマッター、出力形式変換のフォーマッターが必要になり、面倒です。しかし、LangChainであれば各APIのwrapperがすでに提供されているため、アプリケーションに渡すLLMオブジェクトを取り替えるだけでLLMモデルを変更することができます。

## Retrieval

LLMは多くのことを答えることができますが、学習に利用されていない最新情報や社内文書について答えられなかったり、嘘をついたり（ハルシネーション）します。これを防ぐための手段として、RAG（Retrieval-Augumented Generation）があります。RAGは参照したい文書をあらかじめベクトル化し保存したベクトルDBから入力プロンプトに近い意味持った文書を引っ張り出し、LLMに入力することで外部データを参照しつつ質問に答えることができます。

LangChainではさまざまな形式の文書を読み込み、文書データの分割、エンベディング（ベクトル化）indexingのための機能が提供されており、RAGシステムを非常に簡単に組むことができます。

## Chains

LLMは単一のプロンプトのみでは複雑な問題を解くことができないことが多い。これを解決したプロンプトエンジニアリングとして、CoT（Chain of Thought）プロンプティングがある。これは複雑な問題を解く前に問題の解決手順を推論させ、それを元に問題を解決するというプロンプトである。従来のChatGPTでは人間→AI→人間→AIという2段階の手順を踏まないければCoTはできないが、LangChainではChainsという機能を利用することで人間→AI→AIと人間が絡む工程を最初の一つにすることができる。ChainsはLangChainのコア機能であるLCELを利用して簡潔に記述することができる。

## Agent Tooling

AgentとはLLMに利用可能なtoolを持たせ、LLM自身が問題解決のために利用するtoolを決定し実行することを繰り返すことで、LLMが複雑な問題を自律的に解決できるようにするアーキテクチャである。代表的なAgentとしてReAct(Reasoning and Action)がある。Agentはtoolとしてさまざまな関数やAPIを持つことができ、LLMが苦手な計算などを完璧に行うことができる。LangChainではAgentの作成や実行を簡単にできる機能や、自作のpython関数をtoolとしてagentに持たせることができる。

# LangChainを用いたAzure API実行例

最も簡単なLangChainの例として、AzureのGPT-4oのAPIを叩いてみる。（APIの設定は各自行ってください）


```python
import os
from langchain_openai import AzureChatOpenAI

llm = AzureChatOpenAI(
    deployment_name='gpt-4o',
    azure_endpoint=os.environ['AZURE_OPENAI_ENDPOINT'],
    openai_api_key=os.environ['AZURE_OPENAI_API_KEY'],
    openai_api_type='azure',
    openai_api_version='2023-05-15',
    temperature=0
    )

result = llm.invoke('pythonでできることを5個教えてください。')
print(result.content)
```

    もちろんです！Pythonは非常に多用途なプログラミング言語で、以下のようなさまざまなことができます。
    
    1. **ウェブ開発**:
       - フレームワーク（例: Django, Flask）を使用して、動的なウェブサイトやウェブアプリケーションを構築できます。
    
    2. **データ解析と科学計算**:
       - ライブラリ（例: Pandas, NumPy, SciPy）を使用して、大量のデータを解析し、統計的な計算を行うことができます。
    
    3. **機械学習と人工知能**:
       - ライブラリ（例: TensorFlow, Keras, Scikit-learn）を使用して、機械学習モデルやディープラーニングモデルを構築し、トレーニングすることができます。
    
    4. **自動化とスクリプト作成**:
       - 日常的なタスク（例: ファイル操作、ウェブスクレイピング、データの変換）を自動化するためのスクリプトを簡単に作成できます。
    
    5. **ゲーム開発**:
       - ライブラリ（例: Pygame）を使用して、2Dゲームやシンプルなゲームを開発することができます。
    
    これらはPythonの多くの用途の一部に過ぎません。Pythonはそのシンプルさと強力なライブラリのエコシステムにより、さまざまな分野で広く利用されています。
devise_token_authを用いたゲストログイン・ログアウトの実装

自分用のメモとして実装の参考になった記事をまとめておきます。
あまり記事が見つからず探すのが大変でした。


## ゲストログイン
まず全体的な実装方法は下記の記事を参考にした。

https://zenn.dev/kingdom0927/articles/a9ff114b1ee57f

途中、ゲストログインは成功したいるのにフロントエンドのレスポンスヘッダーがアクセストークンを受け取れていない状態になりハマったが、下記の記事を参考にルーティングを設定し直したのと、レスポンス内容を明示したことで解消できた。

https://qiita.com/fumi238000/items/b119c0202f37e687c21c



## ログアウト

https://zenn.dev/kingdom0927/articles/0da51319c52738

途中、ログアウトを実行した際にbypass_sing_inが実行されてしまい、セッションを無効化している状態だとエラーになってしまう問題が発生。下記の記事で解決できました。

https://qiita.com/Kazuyaa/items/2d4065ddf2237c66dfd4

https://github.com/waiting-for-dev/devise-jwt/issues/235
まとめ記事：Robot File System 利用ガイド

# はじめに

これまでバラバラに書いてきた `Robot File System` に関する記事ですが、何気に「`RFS` とは」と人に話す機会も増えてきたので、あらためてまとめ記事化します。

# あらためて Robot File System とは

<iframe width="560" height="386" src="https://www.youtube.com/embed/X1eF6GKUjfM?controls=0&amp;start=48" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

端的に言うと、`net use` コマンドを使わなくてもリモートドライブ上のファイルを操作できるBizRobo!特有の機能です。

https://qiita.com/ParakeetOnTheHead/items/a07d7dadb6b0b1630881

と、それだけだと全く魅力が伝わりませんが、

- ストレージがリモートドライブだろうと、ローカルディスクであろうと、実際の端末のホスト名やIPなどが何であろうと、そういった一切の物理情報を仮想化し、`RFS` をコールすれば同じやり方でファイルの読み書きができる機能。[^1]
- `RFS` を使って目的のファイルにアクセスできる期間を「永続的」に許可することもできれば、「ロボットが動いている間だけ 且つ、許可されたロボットからだけ」とすることもできるので、悪意のある人がロボット実行中や、ロボット実行後にDAS端末を操作して当該ファイルを操作しようとしても `そもそもアクセスできない` ということが可能な高セキュリティ機能
- FTPクライアントとして、FTP[s]サーバとも同様にアクセスが可能なため、リモートドライブと同じ操作性で読み書きできる機能。
- `RFS`サーバは低負荷なサーバのため、個別のサーバを立てる必要はなく、MCとの同居が可能。[^3]

といったメリットもあり、超オススメです。

https://qiita.com/ParakeetOnTheHead/items/6cd8148599bbf6364cb5

:::note
BOXについてはFTP[s]を使ってファイルの読み書きができるオプションがあるため、`RFS` と接続し、直接ファイルをBOXとやり取りすることができます。[^2]
- [FTPまたはFTPSによるBoxの使用](https://support.box.com/hc/ja/articles/360043697414-FTP%E3%81%BE%E3%81%9F%E3%81%AFFTPS%E3%81%AB%E3%82%88%E3%82%8BBox%E3%81%AE%E4%BD%BF%E7%94%A8)
:::

[^1]: 移行も楽々、開発環境や本番環境などの環境差異を考える必要はなし
[^2]: ただし、日本語には対応しておらず、フォルダ名やファイル名に使える文字は英数半角のみのようです。（v11.4時点）
[^3]: 厳密には、当然大量に使用する際には負荷がかかることもあると思うので、負荷の見積もりは必要でしょうが、敢えて負荷テストをしない限り、社内で利用している範囲ではほぼリソースの消費は無風と言っていいレベル。


# それでは使ってみましょう
## 検証環境の構築手順
https://qiita.com/ParakeetOnTheHead/items/7177e81d30275e9b7193

## 組み込みMCの検証環境に併存させる構築手順
https://qiita.com/ParakeetOnTheHead/items/b48d4d9293109858754d

# まとめ

`RFS` は便利だぞ、BizRobo! のセールスポイントだぞ。と、か細い声でこれまで伝えてきましたが、確かに派手な機能ではないため興味をもっていただくには至らず、「`net use` 使ってファイルアクセスしてます。」という情報が耳に入ってくるたびに :thinking: な感じです。

現行は BizRobo! Basic のみを対象とした機能ですが、LITEでは不要なのかな？のに。
投稿マラソン 完走賞の景品が届いた

## ぬいぐるみとキーキャップとボールが届きました

景品が欲しくて投稿マラソン参加しました。無事、完走して景品もらえました。ありがとうございます。

キーキャップはロープロファイルなため使っているキーボードには高さが足りないです。
完全に記念品です。

![IMG_0384.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3812230/b33dd42d-6e01-cebd-bce4-fbf0dbe0c636.jpeg)
![IMG_0385.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3812230/70e4a84f-c606-f2dd-5005-e74a3f40751b.jpeg)

ぬいぐるみかわいい
AWS Peacock Management Consoleの機能を拡張してショートカットリンクをワンクリックで取得できるようにしてみた

# AWS Peacock Management Consoleの機能を拡張してショートカットリンクをワンクリックで取得できるように。

* AWS IAM Identity Centerを利用しているユーザがconfigにサブドメインを設定しておくことで開いているAWSリソースの[shortcut link](https://docs.aws.amazon.com/singlesignon/latest/userguide/createshortcutlink.html?icmpid=docs_sso_console)をピン留めした拡張iconをワンクリックすることで取得できるように機能拡張してみました。

    * 参考：[ショートカットリンク](https://dev.classmethod.jp/articles/iam-identity-center-shortcut-links-aws-access-portal/)
    * レポジトリ：https://github.com/MaSuCcHI/aws-peacock-management-console-fork/tree/aws-shortcut

## 背景
AWSのリソースのURLは、対象のAWSアカウント情報を含んでいないため、共有されたURLを開こうとして、別のアカウントのリソースだということが頻発します。

AWS IAM Identity Centerを利用しているユーザはショートカットリンク作成機能を使うことでアカウント（＋閲覧ロールなど）を指定したURLを発行できるので、社内ドキュメントにAWSリソースへのリンクや、障害時に怪しいリソースのURLを共有する時に便利です。

ただ、わざわざアクセスポータル画面に遷移してショートカットリンクを生成するのが面倒なため、ワンクリックでショートカットリンクを生成しクリップボードにコピーできるようにAWS Peacock Management Consoleを拡張してみました。  

（AWS Peacock Management Consoleを拡張したのはAWSをマルチアカウントで利用のユースケースが近いのとAWSアカウントを取得する処理とかを使いまわせることができるかなと思ったので。。。）


* ※ショートカットリンク作成機能の紹介についてはクラスメソッドさんのこちらの記事がわかりやすかったです。
    * https://dev.classmethod.jp/articles/iam-identity-center-shortcut-links-aws-access-portal/


## ショートカットリンクのコピー
拡張をピン留めした上で、ショートカットリンクを取得したいページでピン留めした拡張機能のiconをクリックすることでショートカットリンクがクリップボードにコピーされます。

（configにてidentityCenterのサブドメインを設定する必要あり）
![Screenshot 2024-08-25 at 15.23.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203831/cb84d3fd-e975-9772-94d2-0d2aaf420941.png)
### Config
本家のAWS Peacock Management Consoleからconfigの書き方も拡張しました。
以下の形式でAWS Access Portalのサブドメインを設定してあげることで機能を使えるようになっています。
例：`https://d-xxxxxxx.awsapps.com/start/#/?tab=accounts` の`d-xxxxxxx`

```
{
  // AWS access portal:
  //   https://{{my_subdomain}}.awsapps.com/start/#/?tab=accounts
  "identityCenter" : "my_subdomain",
  "configs" : [
    {
      "env": {
        "account": "111111111111"
      },
      "style": {
        "navigationBackgroundColor": "#65c89b",
        "accountMenuButtonBackgroundColor": "#945bc4"
      }
    }
  ]
}
```

## 最後に
利用されたいかたは、各自の責任でレポジトリをcloneの上、chromeの開発者モードをオンにした上でご利用していただいたらと思います。
拡張として公開するよりも時間があれば本家のレポジトリにPRを出したいとは思ってますが、一旦自分が使えたらいいやぐらいの気持ちなので時間がある時にやろうかと思います。。
【Nuxt 3】vue3-google-loginをpluginsで使用時に「vue3-google-login cannot be executed on the server side」のエラーが発生

## 概要
[vue3-google-login](https://devbaji.github.io/vue3-google-login/)は、vue3でのgoogleログイン実装用のライブラリですが、Nuxt 3にてpluginsで設定し使用した際、ローカルでサーバを起動時に表題のエラーが発生しました。
今回は原因と対処方法をメモ書きします。

## 前提
* 使用したNuxt.jsのバージョンは`3.12.4`です。
* 使用したvue3-google-loginのバージョンは`2.0.29`です。

## 原因・対処方法
vue3-google-loginのドキュメント[Nuxt 3](https://devbaji.github.io/vue3-google-login/#nuxt-3)の項にある通り、この記事を書いている2024年8月時点ではSSRをサポートしていません。ので、pluginsをクライアント側で読み込む必要があります。
対処としては上記のドキュメントにも書いてありますが、pluginsの設定をしているファイル名に`.client`を付与します。Nuxt 3では[Client-only Nuxt 3 Vue plugin](https://stackoverflow.com/a/73845421)のstackoverflowの記事にある通り、ファイル名でpluginsのクライアント側での読み込みを制御することができます。
今回は`vue3GoogleLogin.client.ts`という名前で、pluginsのファイルを設定すれば大丈夫です。
副作用とその扱いについてケリをつける

### 前提知識

- 副作用とは？
「副作用」という言葉はプログラミングの文脈で広く使われていますが、共通の定義があります。それは、「**関数が外部の状態を変更したり、外部の状態に依存することで、関数の出力が予測不能になること**」です。

✅ **副作用がある関数**
- 外部状態の変更
関数が外部の状態を変更する場合（例: グローバル変数やDOMの状態、APIの呼び出し結果を変更する）。
- 予測不可能な結果
関数が外部の状態に依存しており、同じ入力に対して常に同じ結果を返さない場合（例: 外部APIからのデータに依存する）。

✅ **副作用がない関数**
 関数の出力が入力だけに依存し、関数が実行されても外部の状態を変更しない関数。これは「**純粋関数**」と呼ばれる。同じ入力に対して常に同じ結果を返し、関数の実行がプログラムの他の部分に影響を与えない。

💬具体的にどんなものがあるの？？
- DOMの変更
DOMの操作は外部状態に影響を与えるため、一般的には副作用とされます。ただし、初期レンダリングは変更ではなく描画処理なので副作用とはみなされません。
- APIとの通信
API呼び出しは外部システムの状態に依存して結果が変わるため、引数以外の要因で戻り値が変わる可能性があるため、副作用とみなされます。
- ファイルへの書き込み
これはプログラムの外部（ファイルシステム）に影響を与えるため、典型的な副作用です。
- state/propsの変更
Reactにおいて、useStateやuseEffectを使った操作は、レンダリングサイクルに影響を与えるため、副作用とみなされます。
例）useEffect内でAPI呼び出しを行い、その結果をuseStateで管理する場合、この操作は副作用です。なぜなら、これが行われるとReactは再レンダリングをトリガーし、UIが変わるからです
- オブジェクトや配列の変更
関数内でオブジェクトや配列を変更すると、その変更が関数外にも影響を及ぼす可能性があります（たとえば、参照型データの変更）。この場合も副作用とされます。

## なるべく副作用のない関数を作る（本題）
この議題については、賛否や程度の問題があると思うのですが、ここでは基本的な考え方として「副作用のない関数を作ることに努めるべきである」という立場に身を置きます。

### なぜ副作用のない関数を作った方がいいの？？

副作用を避ける理由は、コードの予測可能性と保守性を高めるためです。

1. **予測可能性**
副作用のない関数は、同じ入力に対して常に同じ結果を返すため、テストやデバッグが容易です

1. **保守性**
副作用のない関数は、他のコードに影響を与えにくいため、コードの変更が他の部分に予期せぬ影響を与えるリスクが低くなります。これにより、コードの保守が容易になります。

### でもAPIコール（副作用）とか絶対に必要だし、どうするべき？
APIコールやファイルへの書き込みなど、副作用が避けられない状況は多々あります。その場合でも、以下の方法を用いて副作用を管理できます。

- **副作用を隔離する**
副作用を持つコードは、できるだけ限定された場所に隔離し、他の純粋な関数から分離します。たとえば、ReactのuseEffectフックを使って、副作用をコンポーネントのライフサイクルに沿って管理します。
- **関数の戻り値に副作用を持たせない**
副作用を引き起こす関数でも、戻り値は副作用の影響を受けないようにします。例えば、APIコールの関数は、その結果を呼び出し元に返すだけで、呼び出し元でその結果を使って状態を更新します。
- **明示的な副作用管理**
ReduxやContext APIを使い、アプリケーションの状態管理を明確に行います。これにより、副作用がどこで起きるかが分かりやすくなります。

## おまけ
### 副作用のある関数と戻り値の関係

- **戻り値がない関数**
通常、必ず副作用を持つ関数です。何かを実行する（例: DOMの更新、API呼び出し etc）ために使われます。
- **戻り値がある関数**
基本的には副作用ではない状態が望ましい。しかし100%戻り値がない = 純粋関数とは限りません。
副作用を持つ関数でも、結果を返すことはもちろんできます。ただし、その関数が外部状態を変更しない、あるいは外部状態に依存しないならば、純粋関数とみなされます。
3DホログラフィックLEDファンを貰ったのでちょっとさわってみた。

# はじめに
先日会社で廃品の整理があり「3DホログラフィックLEDファン」と言うのが出てきたので貰ってきた。こんな漢字のやつ。
![PXL_20240824_232520036.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13477/7a1a788a-1059-5613-1430-ab8ca43d4cfe.jpeg)
![PXL_20240824_233616671.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13477/ea44102e-72d7-67d2-6016-49291018221f.jpeg)

# 組み立て
4枚羽根の方は組み立てが必要。ファンの裏側は基板むき出しでICチップが並んでいて、なかなか野趣あふれる作り。
![PXL_20240824_235640560.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13477/5d180659-85a5-5b04-b8c6-fe5460cd59ff.jpeg)

4枚ファンを組み立てたところ。ネジ8本で固定するだけ。
![PXL_20240824_234950869.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13477/1c18fb83-54f3-966d-2c52-8bd5c525f4ae.jpeg)

# 表示データ
表示データは、マイクロSD(TF)カードで読み込ませる方式。カードリーダーが付属しており、本体の回転部分にスロットがある。
![PXL_20240824_234345138.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13477/3d42fbb0-11a2-036f-7f68-dcb4454804e1.jpeg)

# 製品情報
貰ったときは本体のみで取説などは無し、本体にも型番のようなものは記載なし。というわけで、AliExpressで「3DホログラフィックLEDファン」で検索して、それらしい製品を探す。
![AliExpress.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13477/ad026244-e055-0850-80f8-039cace4f9cc.png)

このあたりがあやしい。結構いい値段が付いていて驚く。(やったね！)
https://ja.aliexpress.com/item/1005004773884711.html
https://ja.aliexpress.com/item/32858826472.html

いろいろ調べた結果、どうやらここが大元のよう。「Z1 (43cm)」と「Z3 (65cm)」と言うのがそれ。英語のマニュアルもダウンロードできる。ただし、簡易マニュアル的な漢字であまり詳しくはない。中身のチップやOSの記載はなし。
http://hologramfan.cn/productCenter.jsp
http://hologramfan.cn/productDocument.jsp

# 動作確認
とりあえず、最初から入っていたマイクロSDカードを差し込み電源を接続する。
4枚ファン。表示されているのはハンバーガーのアニメーション。スマフォのカメラで撮影したので同期の関係で画像が切れているが、肉眼だと結構綺麗に見える。
![PXL_20240824_234907629.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13477/d40d6a10-27d0-fb0c-dcd8-3b7c5b34c985.jpeg)

2枚ファン。表示されているのは、HUAWEIのロゴのアニメーション。写真は画像が切れていても何となくわかる。
![PXL_20240824_234847322.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13477/4b3631fc-c153-4074-a854-3b0b13bca604.jpeg)

【注意】本体に電源スイッチなどはなく、電源ケーブルを差し込むといきなり回り出して大変危ない。また、回転が始まるとトルクがかかって暴れるので、ちゃんと固定した方が良い。
![PXL_20240825_002645094.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13477/b4e46b16-6f93-a3b4-aadd-37c5282b240d.jpeg)

# 最後に
・リモコンが付属しているので使えるか試したい。
・マイクロSD(TF)にmp4ファイルを書き込めば順番に読み込んで再生してくれるよう。オリジナルの動画を作成して試してみたい。
・Z3は、Bluetoothに対応していて、Webインターフェースがあるよう。こちらも試してみたい。
・ファンが高速で回転するので、裸だとかなり危険。実際に使用するときは、手が届かない場所に設置するなど工夫が必要。AliExpressで売られている同様の製品には透明カバーなどのオプションがあるものもある。

以上
Laravelアプリに自作のCSSやJSを読み込ませる (asset関数)

## はじめに
Laravelアプリに自分で作成したCSSやJavaScriptを反映させる場合、それらのファイルを相対パスで指定することも可能ですが、asset関数を使用することでよりシンプルに記述することができます。

https://laravel.com/docs/11.x/helpers#method-asset

## cssファイル、jsファイルの保存先
asset関数は、publicディレクトリ内のファイルのURLを生成するために使用されます。
そのため、各ファイルはプロジェクトルート直下のpublicディレクトリ内に保存します。
今回は以下のようなディレクトリ構造を持つものとします。

```
public
  ├ css
  │  └ style.css
  ├ js
  │  └ script.js
```

## asset関数の書き方
引数にpublicディレクトリからの相対パスを指定します。
例えば、上記のstyle.cssを取得するには以下のように記述します。
```php
asset('css/style.css');
```

## 記述する場所
HTMLファイルに記述する場合と同様に、ビューファイル内の、CSSであればheadタグ内、JavaScriptであればbodyタグの最後に記述するのが一般的です。

```php:cssの場合
<head>
    <link rel="stylesheet" href="{{ asset('css/style.css') }}">
</head>
```

```php:jsの場合
<body>
    <!-- ページのコンテンツ -->

    <script src="{{ asset('js/script.js') }}"></script>
</body>
```
Cloud Functions 第2世代で selenium でスクレイピングする

Cloud Functions を用いて selenium でスクレイピングするとき、もともと次の記事を参考にしてました。
https://blowup-bbs.com/gcp-cloud-functions-python3/

もともと個人開発でスクレイピングをしていた時は上記の記事のやり方でうまく動いていたのですが、久々に環境に手を入れたら動かなくなってしまいました。
原因もよくわからない（たぶんライブラリを更新したせい）ため、一から Functions で selenium を用いてスクレイピングする環境を作りました。

まあまあ手間がかかったので備忘録的に記事にします。

## 手順

### 前提

ライブラリのバージョン
```
selenium==4.15.2
```
### Chrome のダウンロードと配置

Cloud Functions 上で selenium でスクレイピングするには headless Chrome と chromedriver が必要です。

ダウンロードするには [Index of chromium-browser-snapshots/Linux_x64/](https://commondatastorage.googleapis.com/chromium-browser-snapshots/index.html?prefix=Linux_x64/) ページから適当なバージョンの Chrome をダウンロードします。

最新バージョンにしたい場合は一番下のほうにある LAST_CHANGE のファイルに記載のバージョンを確認します。

執筆時点での最新バージョンは [1346408](https://commondatastorage.googleapis.com/chromium-browser-snapshots/index.html?prefix=Linux_x64/1346408/) だったのでそのフォルダを開きます。

そこから chrome-linux.zip と chromedriver_linux64.zip をダウンロードして解凍しておきます。

解凍したものをデプロイするディレクトリに配置します。
chrome-linux.zip を解凍したものを丸ごと配置します。
chromedirver もそのまま配置します。

### コード

```python
import os

from selenium import webdriver
from selenium.webdriver.chrome.service import Service

options = webdriver.ChromeOptions()

# option は適当につける
chrome_options.add_argument('--headless')
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--disable-dev-shm-usage')

path = os.getcwd()
driverPath = os.path.join(path, "chromedriver")
headlessPath = os.path.join(path, "chrome-linux/chrome")
options.binary_location = headlessPath

service = Service(driverPath)
driver = webdriver.Chrome(service=service, options=options)
```

もろもろの Functions を動かす設定は割愛します。
インターンの振り返りと次への意気込み

# はじめに
どうもゆうだいです。
今年の８月のはじめに参加したインターンの振り返りと、明日から二週間のインターンの参加するので振り返りや意気込みを書いていこうかと思います。
初めて記事書くので読みにくいなどがあったらごめんなさい。

# 振り返り
参加したインターンは３日間の対面でのインターンシップで課題解決のために既に社内で使用されているアプリケーションに新たな機能の開発をチームで行うというハッカソンのようなものでした。

既に使用されているアプリケーションはリモートとのハイブリッドでの勤務への移行に伴って発生した「勤務状態が見えにくく、コミュニケーションが取りにくい」という問題の解決のために作られた勤怠管理Webアプリです。

私達のチームもやはりハイブリッド型に伴って発生するであろうコミュニケーションの問題へと着目し、話し合った結果、気軽に質問できる環境作りをしようという方向性で既存のWebアプリに質問箱のような機能をつけようと言う形で進めることになりました。
## チームメンバーについて
触れてなかったので簡単にどんなチームだったのか触れておきます。

今回インターンに参加した人数自体は15人だったのですが、私達は企業側に組んでもらった4人チームで開発に取り組みました。

みんな積極的に話し合いなどに参加してくれる方達で個人的にはすごいやりやすかったなと思っています。
ただ、技術スタックが僕以外、フロント寄りでという感じだったので、開発を行う際はフロント3人バックが僕1人でやることになりここはしんどかったな言う気持ちです。

普段ハッカソンにでるときはみんなバックエンドできる！けどフロントできないみたいな状況で出ることが多かったので今回の状況は新鮮でフロントがちゃんといるとこんなに楽なんだという気持ちになりました。

やっぱりバランスは大事ですね……。

## 開発を通じて感じたこと
まず今回はLaravelとReactを用いた既存のアプリケーションに新たな機能を追加するということで、個人的にはかなり苦戦しました。

というのも普段ハッカソンなどで開発を行うときは0から自分の得意な言語とか作りたいものを考慮しながら技術選定を行い開発をするのですが、既存のものはそれに従って開発していくしかなく、Laravelを触ったのも去年に参加したインターンのときだけだったので普段より開発に時間がかかりながら進めることになりました。

また今まで触れたことがなかった仕組みとしてInertia.jsというサーバーサイドフレームワークと同期してレンダリングができるようなフロントエンドとバックエンドの両方のフレームワークを接続する役割を持つものを使用したのもあってフロントエンドとバックエンドの連携も慣れてなくかなり手間取ったと思います。

ただ救いとしてはエンジニアさんがチームに一人メンターとしてついてくれるだけでなくそれとは別にそのアプリケーションのことならなんでも答えられるエンジニアさんが別で待機してくれていたのもあってほんとにわからないとこはとてもサポートしてもらいながらつまりすぎることはなく進めることができたと思います。

## 反省とか
まず反省としてあげるのはgitの管理かなと思います。今まで結構適当に使ってきた部分があったり、今回はバックエンドを担当するのが自分ひとりだったのもあって、ブランチの切り方とかコミットとかをかなり適当にやってしまってあとから振り返るときに、面倒になってしまった部分があったのでここは今後気をつけようと思います。

あとはチームとしてリーダーを建てなかったり、タスクの細分化なども行っておらず、最終的にアプリケーションの開発が8割くらいでもうちょっと！というところで時間切れになってしまったことがあったので、チームのマネジメントはもっとちゃんと行ったほうが円滑に進んだだろうというの他の反省点ですね。

# まとめと明日からの意気込み
3日間でしたがチームとしっかり連携を取りながら、開発ができたことは凄い貴重な経験になったなと思います。

明日からは二週間のフルリモートでの開発を行うインターンなので詰まったら許される範囲でたくさん社員さんなどを頼りながら自分の力を伸ばしていくことができたらなと考えています。

ここまで読んでくれてありがとうございました！
Cookieとセッションを用いたログインの仕組み

# はじめに
ログイン機能は普遍的なアプリケーションでは基本的に実装されてる機能かと思います。現代のフレームワークである Ruby on Rails や Laravel にもログイン機能用のライブラリや機構が標準で用意されており、我々開発者はとても簡単にログイン機能を実装できるようになりました。

ただ、その導入の便利さと引き換えに内部実装を理解する機会は自ずと減っていき、いざ、複雑なことをしようとすると、全体像が把握できておらず、具体的な説明を求められても、正確に解説できる人は少ないと思います。

今回は、ログイン機能の内部構造を紐解きながら理解を深めるのが主な目的です。

## ログインの全体像
![ログイン.drawio (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550153/42ec9ad0-6e7c-f3a1-8607-efec7df535aa.png)

## セッション ID の生成
ユーザーがセッションを開始すると、サーバーはユーザを一意に識別するためにセッション ID という識別子を生成します。

このセッション ID はセッション保存領域へ保存され、以降のリクエストでは、この保存領域からセッション ID を探してきます。

セッションID がイコールセッションファイルとして生成されます。セッションデータは、セッションIDと同一名であるセッションファイルにデータが保存されていきます。

:::note info

セッション保存領域は基本的にファイルとなっていますが、FW などによっては設定で、redis などのインメモリデータベースであったり、RDB などを選択することができます。
:::

## Set-Cookie ヘッダーにセッション ID をセット
ブラウザに対して Cookie の登録を指示したい場合は、レスポンスヘッダーである Set-Cookie に、名前と値をセットする必要があります。（[RFC6265](https://tex2e.github.io/rfc-translater/html/rfc6265.html)）

レスポンスを受け取ったブラウザは Set-Cookie ヘッダーにセットされているデータを検知し、ブラウザに Cookie として登録します。


:::note warn
文脈によって Cookie という言葉が仕組みを指すのか、データそのものを指すのか変わってくるので、話の流れや文脈で臨機応変に解釈を変えていく必要があります。
筆者もこの記事を書くための調査の過程で、言葉の定義があやふやで混乱しました。
:::

## ブラウザに Cookie を登録
Set-Cookie ヘッダーにデータがあるとき、ブラウザは、そのデータを読み取ります。
読み取ったデータの name と value をペアで登録します。

expire の指定を行うと指定時間を経過するまでブラウザで保持されたままとなるので、永続 Cookie となり、expire の指定を行わないと、ブラウザを閉じた時点で Cookie は破棄されてしまうので、セッション Cookie となります。

:::note info
永続 Cookie の方は言葉からなんとなく意味が推測できたのですが、セッション Cookie の方は最初混乱すると思います。異なる機構であるセッションと Cookie が一単語に入ってたので、？？？ となりました。

セッションという言葉は、なんらかの開始から終了までを指すので、セッションという性質を持っている Cookie と考えると腑に落ちました。
:::


## 参考
https://zenn.dev/bigen1925/books/introduction-to-web-application-with-python/viewer/cookie

https://qiita.com/7968/items/ce03feb17c8eaa6e4672

https://tex2e.github.io/rfc-translater/html/rfc6265.html

https://wa3.i-3-i.info/word15940.html

https://kanda-it-school-kensyu.com/php-basic-contents/pb_ch11/pb_1103/
命名規則のきほんの「き」

# はじめに
プログラミングをしていく上で、命名規則はとても重要です。
例題を紹介しながらアウトプットします。

# 命名規則が重要な理由
命名規則をしっかり行うことで得られる主なメリットは以下になります。

### 可読性の向上
一貫した命名規則を使用することで、コードが読みやすくなります。他の開発者や自分自身が後からコードを見たときに、変数や関数が何を意味しているのかがすぐにわかります。
また、ソースが膨大になり、命名規則がしっかりしていないと、内部の処理をしっかり見る必要があるため、読み手の負荷が大きくなってしまいます。

### メンテナンス性の向上
一貫性のある命名規則は、コードの変更や修正が容易にします。新しい開発者がプロジェクトに参加した場合でも、命名規則に従うことで理解しやすくなり、バグの減少に繋がります。

### コードの再利用性
同じ命名規則を使用することで、異なるプロジェクトやモジュール間でのコードの再利用が容易になります。同様の目的の関数やクラスが一貫した名前を持つため、再利用しやすくなります。

# 種類別の命名パターン
命名のパターンについては、基本的に以下のように考えると良いです。
| 名前の種類 | 命名パターン |
|:--:|:---:|
|変数名、プロパティ|(形容詞+)名詞|
|関数名、メソッド|動詞(+形容詞+名詞)|
|クラス名|(形容詞+)名詞|


# 例題
ここからは、実際にNG例と、OK例のコードを書いていきます。
言語はJavaScriptで書いていきます。

## 変数名
まずは変数名における命名の例です。

### 例1: boolean型を格納する変数
**NG例**
```javascript
const string = typeof "taro" === "string";
```
**OK例**
true or falseを格納する変数は先頭に「is」を付けることが多いです。
```javascript
const isString = typeof "taro" === "string";
```

### 例2: 数値を格納する変数
**NG例**
```javascript
const a = 5;
```
**OK例**
変数名には意味のある名前をつけましょう。例えば、年齢を表す変数の場合:

```javascript
const age = 25;
```
## 関数名
次に、関数名の命名について見ていきます。関数名は「動詞(+形容詞+名詞)」で表現するのが一般的です。

### 例1: 文字列が空かどうかを確認する関数
**NG例**
```javascript
function check() {
  // 何をチェックするのかが不明確
  return input === "";
}
```
**OK例**
何をする関数なのかを明確にするため、名前に動詞を使用します。

```javascript
function isEmpty(input) {
  return input === "";
}
```
### 例2: リストから特定の要素を削除する関数

**NG例**
```javascript
function remove() {
  // 何を削除するのかが不明確
}
```
**OK例**
```javascript
function removeItemFromList(list, item) {
  return list.filter(i => i !== item);
}
```
## クラス名
クラス名は「(形容詞+)名詞」で表現されるのが一般的です。

### 例1: ユーザーを表すクラス
**NG例**
```javascript
class u {
  constructor(name) {
    this.name = name;
  }
}
```
**OK例**
クラス名には、クラスが何を表しているのかを明確に示す名詞を使います。
```javascript
class User {
  constructor(name) {
    this.name = name;
  }
}
```
### 例2: 図形を表すクラス
**NG例**
```javascript
class s {
  constructor(width, height) {
    this.width = width;
    this.height = height;
  }
}
```
**OK例**
```javascript
class Shape {
  constructor(width, height) {
    this.width = width;
    this.height = height;
  }
}
```

# まとめ
適切な命名規則を守ることで、コードの可読性、メンテナンス性、再利用性が大幅に向上します。特に大規模なプロジェクトやチームでの開発では、命名規則の統一が重要です。
この記事で紹介した命名パターンを参考にして、より良いコードを書けるようにしましょう。

# 最後に
他にも色々な記事を書いているので、よければ読んでいってください！

https://qiita.com/hukuryo/items/97797a91d7e2ee0bcabc

https://qiita.com/hukuryo/items/2c07c52ff3386d5d75b9

https://qiita.com/hukuryo/items/ebeb26823f944f143b11
【Unity】VRで左右の目で異なるものを描画するシェーダー

Unityのビルドインパイプラインで左右の目で異なる絵を描画したいときのシェーダー

重要なのは、v2f構造体で`UNITY_VERTEX_OUTPUT_STEREO`を定義、頂点シェーダーで`UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o)`マクロを呼び出し、フラグメントシェーダーで`UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i)`マクロを呼び出すこと。

`unity_StereoEyeIndex`にどちらの目かどうかの情報が入ります。


```hlsl
Shader "Unlit/SpacialPictureShader"
{
    Properties
    {
        _LeftEyeTex("Left Eye Texture", 2D) = "white" {}
        _RightEyeTex("Right Eye Texture", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;

                UNITY_VERTEX_OUTPUT_STEREO // シングルパスステレオレンダリングで必要なパラメーター構造体
            };

            sampler2D _LeftEyeTex;
            sampler2D _RightEyeTex;
            float4 _MainTex_ST;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                UNITY_TRANSFER_FOG(o,o.vertex);

                // unity_StereoEyeIndexを頂点シェーダーからフラグメントシェーダーに転送するためのマクロ
                UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); 

                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                // このマクロを使用することでunity_StereoEyeIndexにフラグメントシェーダーでアクセスできるようになる。
                UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
                
                fixed4 col = fixed4(0, 0, 0, 1);

                if (unity_StereoEyeIndex == 0)
                {
                    // 左目の場合の処理
                    col = tex2D(_LeftEyeTex, i.uv);
                }
                else
                {
                    // 右目の場合の処理
                    col = tex2D(_RightEyeTex, i.uv);
                }

                // apply fog
                UNITY_APPLY_FOG(i.fogCoord, col);
                return col;
            }
            ENDCG
        }
    }
}
```
goldfish-models/tha_thai_1000mbは「แม่อย่าเก็บไว้คนเดียว」をどうトークナイズするのか

Tyler A. Chang, Catherine Arnett, Zhuowen Tu, Benjamin K. Bergen『[Goldfish: Monolingual Language Models for 350 Languages](https://arxiv.org/abs/2408.10441)』を横目に、タイ語GPT2モデル[goldfish-models/tha_thai_1000mb](https://huggingface.co/goldfish-models/tha_thai_1000mb)のトークナイザを試してみた。

```
>>> from transformers import AutoTokenizer
>>> tkz=AutoTokenizer.from_pretrained("goldfish-models/tha_thai_1000mb")
>>> print(tkz.convert_ids_to_tokens(tkz("แม่อย่าเก็บไว้คนเดียว")["input_ids"]))
['[CLS]', '▁แม่', 'อย่า', 'เก็บไว้', 'คนเดียว', '[SEP]']
```

「[แม่อย่าเก็บไว้คนเดียว](https://qiita.com/KoichiYasuoka/items/851bbe0299f43c7eb4e9)」をトークナイズしてみたところ、「แม่」「อย่า」は正しくトークナイズできているものの、「เก็บ」「ไว้」「คน」「เดียว」がくっついてしまっている。ちなみに、[4月11日の記事](https://qiita.com/KoichiYasuoka/items/e378e737e2978b988983)の2行目を「`models=["goldfish-models/tha_thai_1000mb","goldfish-models/tha_thai_100mb","goldfish-models/tha_thai_10mb","goldfish-models/tha_thai_5mb"]`」に変えて、[UD_Thai-PUD](https://github.com/UniversalDependencies/UD_Thai-PUD)によるトークナイザ・ベンチマークを実行した結果は以下の通り。

```
*** goldfish-models/tha_thai_1000mb
Precision 0.3858722561478792
Recall    0.31421915598960665
F1 Score  0.3463789229363688

*** goldfish-models/tha_thai_100mb
Precision 0.3858722561478792
Recall    0.31421915598960665
F1 Score  0.3463789229363688

*** goldfish-models/tha_thai_10mb
Precision 0.39382404975071034
Recall    0.32909237523519397
F1 Score  0.3585600976205003

*** goldfish-models/tha_thai_5mb
Precision 0.4029943855271366
Recall    0.3472807096138339
F1 Score  0.37306896385774097
```

タイ語専用のトークナイザにしては、Recallがあまりに低すぎる。350種類もの言語に挑戦する心意気は買うが、それでも各言語ごとのクセをちゃんと見極めてから、言語モデルの設計をしてほしいなあ。
UbuntuでMinicondaをインストール


# Miniforgeのインストールと仮想環境のセットアップ

## 1. Miniforgeのインストール

### 1.1 Miniforgeのインストールスクリプトをダウンロード
```bash
wget https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-Linux-x86_64.sh
```

### 1.2 インストールスクリプトの実行
```bash
bash Miniforge3-Linux-x86_64.sh
```
- インストールの際に表示される説明や質問に対して「Enter」や「Yes」を入力してください。
- インストール完了後、`/home/ubuntu/miniforge3` フォルダが作成されます。

### 1.3 インストール確認
Miniforgeが正しくインストールされたか確認するために、以下のコマンドを実行します。
```bash
conda info
```
- 出力例:
  ```
  active environment : base
  active env location : /home/ubuntu/miniforge3
  shell level : 1
  ...
  ```

## 2. 仮想環境の作成とセットアップ

### 2.1 仮想環境の作成
`py39` という名前のPython 3.9仮想環境を作成します。
```bash
conda create --name py39 python=3.9
```

### 2.2 仮想環境の確認
仮想環境が正しく作成されたか確認します。
```bash
conda env list
```
- 出力例:
  ```
  base                  *  /home/ubuntu/miniforge3
  py39                     /home/ubuntu/miniforge3/envs/py39
  ```

### 2.3 仮想環境の有効化
作成した仮想環境 `py39` を有効化します。
```bash
conda activate py39
```

### 2.4 必要なパッケージのインストール
- Pandasのインストール:
  ```bash
  conda install pandas
  ```
- インストールされているパッケージの確認:
  ```bash
  conda list
  ```
- NotebookとIPython Kernelのインストール:
  ```bash
  conda install notebook ipykernel
  ```

### 2.5 Jupyter Notebookの設定
- IPython Kernelを設定:
  ```bash
  ipython kernel install --user --name py39
  ```
- Jupyter Notebookを起動:
  ```bash
  jupyter notebook
  ```

---
Gradle: タスクの依存関係の図を描く（Graphviz 使用）

<!-- [f:id:sonota88:20240728134550p:plain] -->
![lr.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234055/1ead4546-c8a0-f51f-d3fa-c13a888c39c7.png)

タスク間の依存関係を出力してくれる Gradle プラグインはあるようなのですが、木じゃなくてグラフ（DAG）で見たかったり、プラグイン使わなくても済むならそれでもいいな……みたいな気分があって自前で書いてみました。

Gradle 8.9 で確認しました。

（他所で書いていたものを引っ越してきました。元の公開日は 2024-07-28 です。）


# 手順

## (1) build.gradle に以下を追記

```groovy
def generateDotSrc(tasks, idMap, edges) {
  def nodePart = ""

  tasks.each { task ->
    def id = idMap[task]
    def style = ""
    if (task.getActions().size == 0) {
      style = "dashed"
    }
    def label = task.getName()
    // def label = "${task.getProject().getName()}\\n${task.getName()}"
    nodePart += """  ${id} [ label = "${label}"; style = "${style}"; ];""" + "\n"
  }

  def edgePart = ""

  edges.each { taskFrom, taskTo ->
    def idFrom = idMap[taskFrom]
    def idTo = idMap[taskTo]
    edgePart += "  ${idFrom} -> ${idTo};" + "\n"
  }

  """
digraph {
  graph [
    rankdir = LR; // 左 → 右の向きに配置
  ];
  node [
    fontname = "monospace";
  ];

  ${nodePart}

  ${edgePart}
}
  """
}

gradle.taskGraph.whenReady { taskExecutionGraph ->
  def tasks = taskExecutionGraph.getAllTasks()
  // .findAll { task -> task.getProject().getName() == "..." } // 必要に応じて

  def edges = []
  tasks.each { taskFrom ->
    taskExecutionGraph.getDependencies(taskFrom).each { taskTo ->
      edges << [taskFrom, taskTo]
    }
  }

  def idMap = [:] // task => node id
  tasks.eachWithIndex { task, i ->
    idMap[task] = "n${i}"
  }

  def dotSrc = generateDotSrc(tasks, idMap, edges)
  // println dotSrc
  file("task_graph.dot").text = dotSrc
}
```

- [TaskExecutionGraph (Gradle API 8.9)](https://docs.gradle.org/8.9/javadoc/org/gradle/api/execution/TaskExecutionGraph.html)
- [Task (Gradle API 8.9)](https://docs.gradle.org/8.9/javadoc/org/gradle/api/Task.html)




## (2) 実行して Graphviz 用のコードを出力

```sh
gradle {タスク名} --dry-run

  # 例
gradle build --dry-run
  # → task_graph.dot に出力される
```

- 実際にタスクを実行する必要はなくて図が欲しいだけなので `--dry-run` を付けて実行する
- タスクが実行されてもよいなら `--dry-run` なしでもいい




## (3) Graphviz で画像を生成

```sh
dot -Tsvg task_graph.dot > task_graph.svg
```

<!-- [f:id:sonota88:20240728134550p:plain] -->
![lr.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234055/1ead4546-c8a0-f51f-d3fa-c13a888c39c7.png)


こういう図ができあがります。枠が破線になっているのはアクションを持たない集約用のタスク。

<!-- [f:id:sonota88:20240728150929p:plain] -->
![rl.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234055/3f69b834-391e-7e9f-a3f2-1346802e7e79.png)


依存先が左に来るようにしたもの。Gradle のドキュメントで見かけるのはこっちのスタイルですね。




# メモ

```groovy
gradle.taskGraph.whenReady { taskExecutionGraph ->
  taskExecutionGraph.getAllTasks()
}
```

でタスクの一覧が取得できるのと、

```groovy
taskExecutionGraph.getDependencies(taskFrom)
```

で各タスクの依存先タスクを取得できるところがポイント。グラフを描くのに必要な情報はこれで揃う。

なので、たとえば build.gradle ではノード・エッジの情報を抜き出して出力するところだけ行って残りは別のプログラムに任せる作りにすれば、 build.gradle 側の責務をより小さくできる。




# 参考

- [All about the Gradle task graph | Tom Gregory](https://tomgregory.com/gradle/all-about-the-gradle-task-graph/)
CSVを表示する簡易htmlツール

# 0.はじめに
CSVを参照したいけどエクセルがないし、入れられない。あってもインストールが手間。などという時があったので、htmlで参照できるように作ってみました。

# 1.作り方

- メモ帳で新規テキストを作成し、以下のコードを張り付けます。

```html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSVReader</title>
    <style>
        table {
            width: 100%;
            border-collapse: collapse;
            margin: 20px 0;
        }
        th, td {
            padding: 10px;
            border: 1px solid #ddd;
            text-align: left;
        }
        th {
            background-color: #f4f4f4;
        }
    </style>
</head>
<body>

    <h1>CSVReader</h1>
    
    <!-- CSVファイルを選択用input -->
    <input type="file" id="csvFileInput" accept=".csv" />

    <!-- テーブルを表示要素 -->
    <table id="csvTable"></table>

    <script>
        document.getElementById('csvFileInput').addEventListener('change', function(event) {
            const file = event.target.files[0];
            if (file) {
                const reader = new FileReader();
                reader.onload = function(e) {
                    const content = e.target.result;
                    displayCSV(content);
                };
                reader.readAsText(file);
            }
        });

        function displayCSV(content) {
            const rows = content.split('\n').map(row => row.split(','));
            let table = '<tr>';
            rows[0].forEach(header => {
                table += `<th>${header.trim()}</th>`;
            });
            table += '</tr>';
            
            for (let i = 1; i < rows.length; i++) {
                table += '<tr>';
                rows[i].forEach(cell => {
                    table += `<td>${cell.trim()}</td>`;
                });
                table += '</tr>';
            }

            document.getElementById('csvTable').innerHTML = table;
        }
    </script>

</body>
</html>

```

- 張り付けたテキストデータを`CsvReader.htm`というファイル名に書き換えます。

::: note info 
- ここでは`CsvReader`としましたが、名称は任意のものでよいです。
- 拡張子表示していないとテキストデータは`新規 テキスト ドキュメント`などという名称になっています。拡張子表示にしたうえで、拡張子も`txt`から`htm`に変更してください。
:::

# 2.使い方

- `CsvReader.htm`を実行します。

- `ファイルを選択`をクリックしてCSVファイルを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599902/b0ac8f9c-1e99-f13c-d003-dbc3bae097f6.png)

こんな感じで表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599902/4b3e84a1-bdab-7907-0790-fd8dff7bf0e8.png)

これを表示しているCSVは以下のものです。
```csv
Clm1,Clm2,Clm3,Clm4,Clm55
りんご,2024/08/24,2024/08/25,1000,1箱
ぶどう,2024/08/24,2024/08/26,
なし,2024/08/24,,800,2箱
,2024/08/24,2024/08/26,800,3箱
```

# その他

このCSVReaderはよくあるカンマ区切りをデリミタにしていますが、他のデリミタを使用している場合は以下を書き換えて下さい。
```javascript
const rows = content.split('\n').map(row => row.split(','));
```
例えば空白区切りにしたい場合は以下のように書き換えます
```javascript
const rows = content.split('\n').map(row => row.split(' '));
```
Effectの日本語版ドキュメントを勝手につくった

公式ページは以下。

https://effect.website/

作成した日本語ドキュメントは以下。

https://effect-doc-ja.vercel.app/

Effectというライブラリがあります。fp-tsの後継となるプロジェクトで、最近書いていたfp-tsの解説記事が終わったらEffectへの橋渡しとなる記事を書こうと考えていました。ただ、先に日本語ドキュメントを用意したほうが良いな、と思ったのでしてみました。

ChatGPTのAPIでmarkdownをすべて読み込み、それを日本語訳にするだけである程度読みやすい日本語ドキュメントになるのでは、ということで作成してみました。自動翻訳なので、翻訳として甘い部分、表記ゆれの部分があるので、そこは適宜読んだあとに直していく予定です。とはいえ、公式のページがどんどん加筆修正されていくと思うので、どうやって追っていくのか、なども検討しないといけません。pull requestを見て修正されたらついていく、みたいな感じを予定。

一応、公式のissueには上げておきましたが、i18n対応は時間がかかりそうなので自分で勝手にやってます。

公式はnextが採用されていますが、これのdevが本当に遅くてどうしようもない。あまりの遅さに腹がたったので勝手にastroで作成しました。もし公式にi18n対応をしてもらえるならば、mdxだけアップすれば良いので特に問題はないかと思います。
VHDL to verilog

# 概要
VHDLをverilogに変換してみた。

# 環境
wsl(wsl2じゃない)
windows11
ubuntu22.04

# インストール手順

```
git clone https://github.com/YosysHQ/yosys.git
cd yosys
make config-clang
git submodule update --init
make -j$(nproc)
sudo make install

```
```
git clone https://github.com/ghdl/ghdl.git
cd ghdl
./configure --prefix=/usr/local
make -j$(nproc)
sudo make install

```
```
git clone https://github.com/ghdl/ghdl-yosys-plugin.git
cd ghdl-yosys-plugin
make GHDL=/usr/local/bin/ghdl -j$(nproc)
sudo make GHDL=/usr/local/bin/ghdl install
```

# 動作確認

test.vhd
```
library IEEE;
use IEEE.std_logic_1164.all;
entity ORing is
port (A, B: in std_logic; Y: out std_logic);
end ORing;
architecture RTL of ORing is
begin
        Y <= A or B;
end;
```

# 変換スクリプト

```
$ yosys -m ghdl -p 'ghdl test.vhd -e ORing; write_verilog test.v'

```

# 実行結果

```

 /----------------------------------------------------------------------------\
 |  yosys -- Yosys Open SYnthesis Suite                                       |
 |  Copyright (C) 2012 - 2024  Claire Xenia Wolf <claire@yosyshq.com>         |
 |  Distributed under an ISC-like license, type "license" to see terms        |
 \----------------------------------------------------------------------------/
 Yosys 0.44+60 (git sha1 72f77dd97, clang++ 14.0.0-1ubuntu1.1 -fPIC -O3)

-- Running command `ghdl test.vhd -e ORing; write_verilog test.v' --

1. Executing GHDL.
Importing module ORing.

2. Executing Verilog backend.

2.1. Executing BMUXMAP pass.

2.2. Executing DEMUXMAP pass.
Dumping module `\ORing'.

End of script. Logfile hash: ac7f4e6e39, CPU: user 0.04s system 0.01s, MEM: 17.77 MB peak
Yosys 0.44+60 (git sha1 72f77dd97, clang++ 14.0.0-1ubuntu1.1 -fPIC -O3)
Time spent: 90% 1x ghdl (0 sec), 5% 2x write_verilog (0 sec), ...

```

# 生成されたverilog

```

/* Generated by Yosys 0.44+60 (git sha1 72f77dd97, clang++ 14.0.0-1ubuntu1.1 -fPIC -O3) */

module ORing(A, B, Y);
  wire _0_;
  input A;
  wire A;
  input B;
  wire B;
  output Y;
  wire Y;
  assign _0_ = A | B;
  assign Y = _0_;
endmodule
```

以上。
GCP Static IP Addressを別のProjectに移動する (失敗)

## Document

以下のドキュメントでは以下のように書かれていて、IPv4アドレスが移動できるとのこと！便利！

> 静的外部 IPv4 アドレスは Google Cloud プロジェクトに関連付けられ、そのプロジェクト内でのみ使用できます。ただし、プロジェクト間で静的外部 IPv4 アドレスを移動することはできます。

https://cloud.google.com/vpc/docs/move-ip-address-different-project?hl=ja


## gcloud

```
gcloud compute addresses move <ip address name>
 \
    --target-project=<distination project> \
    --region=asia-northeast1 --project <source project>
```

:::note alert

以下のエラーで移動できず

```
ERROR: (gcloud.compute.addresses.move) Could not fetch resource:
 - Quota exceeded for quota metric 'Address move requests' and limit 'Address move requests per minute per region' of service 'compute.googleapis.com' for consumer 'project_number:xxxx'.
```
:::


## Quota

`Address move requests per minite per region` のQuotaを見てみると `0`.

![Screenshot 2024-08-25 at 13.30.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7059/d5cd17c2-7ea7-b2f0-eb07-39a3e3ac68e1.png)

## 結論

特定のRegionでないとできないのかもしれない?

まだ深掘りしてないので、また気が向いたときに更新予定。

## References

1. https://www.googlecloudcommunity.com/gc/Google-Cloud-s-operations-suite/Quota-Exceeded-Address-Move-Requests-error-migrating-static-IP/td-p/671696