OmniAICreator/Qiita-1.07M huggingface dataset:
[ERC5409] ERC1155形式のNFTの保有者を確認する仕組みを理解しよう！

# はじめに

『DApps開発入門』という本や色々記事を書いているかるでねです。

https://amzn.asia/d/gxvJ0Pw

今回は、ERC1155の保有者を確認する仕組みを提案している**ERC5409**についてまとめていきます！

:::note info
以下にまとめられているものを翻訳・要約・補足しながらまとめていきます。
:::

https://eips.ethereum.org/EIPS/eip-5409

他にも様々なEIPについてまとめています。

https://cardene.notion.site/ERC-EIP-2a03fa3ea33d43baa9ed82288f98d4a9?pvs=4

# 概要

**ERC5409**は、**ERC1155**に「`ownerOf`」という新しい関数を追加して、**ERC1155**トークンにも「非代替性」を持たせることを目的としています。
通常、非代替トークン（NFT）の代表的な規格は**ERC721**ですが、**ERC721**は柔軟性が低いという課題があります。
**ERC5409**では、**ERC1155**の効率性や柔軟性を保ったまま、**ERC721**のように「**このトークンは誰が所有しているのか？**」を簡単に確認できるようにします。

# 動機

**ERC1155&&では、あるトークンが「**本当に1つしか存在しないユニークなもの（＝非代替）**」なのか、それとも複数人が持てる「**代替可能なもの**」なのかを、外部からは判別できません。
トークンの発行数（`supply`）が「`1`」かどうかを確認する手段が標準では用意されておらず、仮に1であっても誰が所有しているのかを直接確認する方法がありません。

**ERC1155**の仕様内では、「**トークンIDを工夫して非代替トークンを表現する**」といった方法も紹介されていますが、標準的な手法ではなく、**ERC721**の`ownerOf`のようにシンプルではありません。

今回の提案で`ownerOf`関数を追加すれば、特定のトークンが「**誰のものか**」をコントラクトを通して確認できるようになります。
これにより、所有者がそのトークンにメタデータを紐づけたり、所有情報を活用するような新しいユースケースにも対応できるようになります。

# 仕様

**ERC5409**では、**ERC1155**に新しく`ownerOf`という関数を導入します。
これは、トークンの所有者アドレスを取得するための関数です。

```js:IERC1155OwnerOf.sol
interface IERC1155OwnerOf {
    /// @notice NFTの所有者を取得する
    /// @dev アドレスがゼロ（0x0）の場合は、存在しないか、供給数が1を超えている（＝NFTではない）ことを意味します
    /// @param tokenId NFTのID
    /// @return 所有者アドレス
    function ownerOf(uint256 tokenId) external view returns (address);
}
```

また、`supportsInterface`関数において `0x6352211e` を渡した場合、必ず `true` を返す必要があります。

# 補足

この`ownerOf`関数は、対象のトークンが存在しない場合や、NFTでない場合（例えば供給数が1以上あるような代替可能トークンの場合）でも、エラーを投げずにゼロアドレス（`0x0`）を返します。

これにより、呼び出し側のコントラクトやアプリケーションが「**このトークンは誰のものか？**」という確認をする時に、例外処理を気にせず安全に扱えるようになります。

例えば、**ERC721**では所有者が存在しない場合にエラーが返されることがありますが、すべての**ERC721**実装が必ずそうなる保証はありません。
そのため、今回の仕様ではあえて例外を出さず、常にアドレスを返す形式としています。
この設計によって、**ERC721**に近い使い方をしつつも、安全で扱いやすい形を実現しています。

# 引用

Ronan Sandford (@wighawag), "ERC-5409: EIP-1155 Non-Fungible Token extension [DRAFT]," Ethereum Improvement Proposals, no. 5409, July 2022. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-5409.

# 最後に

今回は「ERC1155の保有者を確認する仕組みを提案している**ERC5409**」についてまとめてきました！
いかがだったでしょうか？

質問などがある方は以下のTwitterのDMなどからお気軽に質問してください！

[Twitter @cardene777](https://twitter.com/cardene777)

他の媒体でも情報発信しているのでぜひ他も見ていってください！

https://chaldene.net/

https://zenn.dev/heku

https://cardene.substack.com/

https://mirror.xyz/0xcE77b9fCd390847627c84359fC1Bc02fC78f0e58

https://cardene.notion.site/ERC-EIP-2a03fa3ea33d43baa9ed82288f98d4a9?pvs=4
個人的備忘録：またIAMか…。ECSタスク起動でつまずいたので、設定を見直してまとめてみた

## はじめに
ECS上でタスクを起動しようとした際に、IAMロール関連のエラーが発生することがあります。

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

本記事では、実際に遭遇した以下のエラーに対する原因と解決策を、備忘録としてまとめます。

## エラーメッセージ
```
service aa failed to launch a task with (error ECS was unable to assume the role 'arn:aws:iam::xxx:role/ecsTaskExecutionRole' that was provided for this task. Please verify that the role being passed has the proper trust relationship and permissions and that your IAM user has permissions to pass this role.).
```

## 接続エラーの原因と解決策
このエラーは、Amazon ECS がタスクを起動しようとした際に、指定された IAM ロール（ecsTaskExecutionRole）を引き受けることができなかったことが原因です。

### 原因
1. **信頼関係（Trust Relationship）の設定ミス**
   - ecs.amazonaws.com がロールを引き受けられるようになっていない

2. **必要なポリシーがアタッチされていない**
   - AmazonECSTaskExecutionRolePolicy などが付与されていない

3. **IAMユーザーに iam:PassRole 権限がない**
   - IAMユーザーが ecsTaskExecutionRole を渡す許可がない

### 解決方法
#### 1. 信頼関係を確認・修正
IAM ロール `ecsTaskExecutionRole` の信頼関係タブを以下のように設定：
```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "ecs-tasks.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```

#### 2. 必要なポリシーをアタッチ
以下のポリシーを付ける：
- `AmazonECSTaskExecutionRolePolicy`

#### 3. iam:PassRole 権限を追加
IAMユーザーまたは使用中のロールに以下のようなポリシーを追加：
```json
{
  "Effect": "Allow",
  "Action": "iam:PassRole",
  "Resource": "arn:aws:iam::xxx:role/ecsTaskExecutionRole"
}
```

## まとめ
このエラーは ECS タスクの起動において、IAM ロールの信頼関係と権限が正しく構成されていないと発生します。以下の3点をチェックすることで解決できるケースがほとんどです：

- ecs-tasks.amazonaws.com を信頼できるエンティティに設定
- 必要な IAM ポリシー（AmazonECSTaskExecutionRolePolicy）のアタッチ
- IAM ユーザー／ロールに iam:PassRole 権限の付与

ECSのデプロイエラーはIAMに起因することが多いため、慌てずにロール設定とポリシーを順番に確認してみてください！
141. Linked List Cycle

# 問題内容
入力されたリストの中にサイクルが存在するか判定する

# 解答例
```python:sample
class Solution:
    def hasCycle(self, head: Optional[ListNode]) -> bool:
        slow_pointer = head
        fast_pointer = head
        while fast_pointer and fast_pointer.next:
            slow_pointer = slow_pointer.next
            fast_pointer = fast_pointer.next.next
            if slow_pointer == fast_pointer:
                return True
        return False
```

# この問題のポイント
* 移動速度の違う変数が２つ
* 遅い方は１つずつ進み、早い方は２つずつ進む
* サイクルが存在すれば、早い方が遅い方と同じインデックスになりTrueを返す
* サイクルがないときは、早い方が終点について終了しFalseを返す
ContentNote : 拡張メモ

[まとめページに戻る](https://qiita.com/Keiji_otsubo/items/60afc2a8d211b6f7d89f)
[まとめN～Z](https://qiita.com/Keiji_otsubo/items/92f92bb9f668ca9688be)

-----------------

# 一括インポート

+ [メモ　を一括エクスポートする方法](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000MZT2t)

:::note
メモはなかなか面倒なオブジェクトですよね。 
以下のヘルプで２段階の処理をしてデータローダからエクスポートする方法が説明されています。 

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

アイデアに上がってはいるんですが... 実現しそうにないです。 
https://ideas.salesforce.com/s/idea/a0B8W00000GdjTaUAJ/reporting-on-notes-attachments

開発者コンソールでクエリーを実行したら、検索はできます。 
Bulk APIを直接使えば、このクエリーを出力できるとは思います。 
TextPreviewという項目を使った方が内容の確認が簡単そうです。
ただ気になるのは共有されていないメモがちゃんと出力できるかですね。 
システムモード（管理者権限）で実行して確認する必要があるとは思います。 

```
select Id,Title,TextPreview,Content from ContentNote
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/ff22c8cd-84a6-4f27-bfde-06177d442fc6.png)

:::


# コーディング例

+ [商談に紐づくカスタムオブジェクトのメモを商談のメモに複数転記する](https://qiita.com/Keiji_otsubo/items/890c6c09842e8d6e8e6b)
+ [項目として運用しているメモフィールドを拡張メモとしてセットする](https://qiita.com/Keiji_otsubo/items/7c4448f2d3e6a5fcb991)
+ [Notes と Notes & Attachments にApexトリガーでレコードを作成する](https://qiita.com/Keiji_otsubo/items/3c1b8f76a20bf969a06b)
+ [すべての商談メモと添付ファイルをアカウントに統合するにはどうすればよいですか?](https://qiita.com/Keiji_otsubo/items/037311b5ec7db0b62528)
SAP Build Process AutomationでBAPIのアクションを作成

Build Process AutomationでBAPIのアクションを作成する手順を紹介します。

## ステップ
1. Cloud Connectorの設定
1. Destinationの登録
1. アクションプロジェクトの登録

## 1. Cloud Connectorの設定
Cloud ConnectorにRFC用の設定を追加します。

参考

https://community.sap.com/t5/technology-blogs-by-sap/configure-cloud-connector-for-rfc-connection-from-cloud-to-on-premise/ba-p/13440178

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/0c3d8297-83de-40f5-8302-7f9113ad74e2.png)

Resourcesに許可するBAPIまたはRFC汎用モジュールの接頭辞を追加します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/fe92ab3f-a840-4495-94a6-ea2aaba8c164.png)

## 2. Destinationの登録
以下のヘルプを参考に、Destinationを登録します。

https://help.sap.com/docs/connectivity/sap-btp-connectivity-cf/create-rfc-destinations

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/6930a7f3-e8ee-4b4e-a02b-9096089b489a.png)

:::note
【重要】
`jco.client.lang`を設定しないとBAPIの呼び出し時にエラーになります。
:::

## 3. アクションプロジェクトの登録
SAP Build Process Automationで**Control Tower > Destinations** より、Destinationを追加します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/7c43e63d-78c6-413b-b653-d7fe9b7c4e44.png)

**Actions > BAPI's RFC's**より、使用するBAPIを選択します。
※Destinationが1つしかないので、自動的にそのDestinationが選択されています
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/be6229ab-02e5-4acc-a645-47b3dbb3a7a0.png)

ウィザードに沿って進み、新規プロジェクトを登録します。

以下が登録されたプロジェクトです。"Test"タブからDestinationを選択し、必要なパラメータを指定してテスト実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/333d779f-92b7-47af-9a02-cf9e736701bb.png)

結果が返ってきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276021/b0e79d10-9011-4f8d-ae97-5342affd62fb.png)
Geminiでランサーを描いてみた。

# 概要

Geminiでランサーを描いてみました。

# 実装

以下のリクエストをしました。

```
炎の槍を使うランサーを描いてください。
```

![炎の槍を使うランサー_20250405.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192024/e334d787-9aa5-48d3-8fdf-36f54a78a10c.png)

```
氷の槍を使うランサーを描いてください。
```

![氷の槍を使うランサー_20250405.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192024/ec1f8cef-bfb9-40dd-82d9-f4e7b19d5b25.png)

```
電撃の槍を使うランサーを描いてください。
```

![電撃の槍を使うランサー_20250405.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192024/f956b208-ba5e-4b53-b753-8b26901f35db.png)

```
光の槍を使うランサーを描いてください。
```

![光の槍を使うランサー_20250405.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192024/ae3b01d3-00d0-417d-97e6-7abe329a5055.png)

```
水の槍を使うランサーを描いてください。 
```

![水の槍を使うランサー_20250405.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192024/b7c098ca-9cce-4089-89f6-22e65a403a67.png)

```
音の槍を使うランサーを描いてください。
```

![音の槍を使うランサー_20250405.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192024/b1a991ee-22c8-4027-aa39-ae15e1d0e4e2.png)

最後の絵はよくわからないが、何か描いてくれている。

# まとめ

何かの役に立てばと。
Azure Speech Service

[Azure OpenAI Text to speech で今日の天気予報を読み上げる #logicapps - Qiita](https://qiita.com/e99h2121/items/6ee8850f92e198162929#http-%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88) の補足メモ。

## Azure Speech Service

https://learn.microsoft.com/ja-jp/azure/ai-services/speech-service/overview

https://learn.microsoft.com/ja-jp/azure/ai-services/speech-service/get-started-text-to-speech?tabs=windows%2Cterminal&pivots=programming-language-rest

## Rest API

### トークン取得

```
POST https://japaneast.api.cognitive.microsoft.com/sts/v1.0/issueToken
Ocp-Apim-Subscription-Key: <Key>
```

### mp3 生成
```
POST https://japaneast.tts.speech.microsoft.com/cognitiveservices/v1
X-Microsoft-OutputFormat: riff-24khz-16bit-mono-pcm
Content-Type: application/ssml+xml
Authorization: Bearer <Token>

<speak version='1.0' xml:lang='ja-JP'><voice xml:lang='ja-JP' xml:gender='Male'
    name='ja-JP-AoiNeural'>
        こんにちは！
</voice></speak>
```

以上です～
マークダウン記法で競プロの問題文っぽいフォントを使う方法

## 結論
- "$"で挟むとそれっぽくなる
- 不等式は "\leq" を"$"で挟むとそれっぽくなる

以下は具体例で、黒い背景がマークダウン記法で、その下が記事になったときの文章になります。"$"でくくった文字の配置に違和感がありますが、直し方はわからないです()

## 例1
```
長さ $N$ の数列 $A$ が渡されます。
```
長さ $N$ の数列 $A$ が渡されます。

## 例2
```
$ 0 \leq A[i] \leq N $
```
$ 0 \leq A[i] \leq N $
MCP対応したVS CodeでAWS MCPを使う

## はじめに

つい昨日に以下の記事を書いたのですが、VS CodeのStable版もほぼ同日にエージェント機能が追加されました。以下の記事ではClaude Desktopを使いましたが、VS Code + GitHub Copilot でも [awslabs/mcp](https://github.com/awslabs/mcp) を試してみます。 

https://qiita.com/ny7760/items/3aa185c65889d66da0dc

なお、部分的に前回の記事に飛ばすとわかりにくかったので、手順については重複する部分もこちらの記事に載せています。


## 前提

#### 環境

- Mac OS 14.5
- VS Code **March 2025 (version 1.99)**
- GitHub Copilot

#### 準備

[awslabs/mcp](https://github.com/awslabs/mcp) はPythonで書かれており、公式の手順ではパッケージマネージャーの `uv` が必要になります。

- `uv` のインストール（[Astral公式ドキュメント](https://docs.astral.sh/uv/getting-started/installation/)または[GitHub](https://github.com/astral-sh/uv#installation)参照）
- Python 3.10 以上 （公式では `uv python install` が推奨されてますが asdf のPythonでも動きました）

:::note warn
最新版は[公式ドキュメント](https://awslabs.github.io/mcp/servers/aws-documentation-mcp-server/)を参照してください。
:::


## 設定方法


#### 1. VS Code のエージェントモード有効化

MCPを利用するためにエージェントモードを有効化します。設定から`chat.agent.enabled` で検索するか、[リリースノート](https://code.visualstudio.com/updates/v1_99)から遷移するのが早いです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/451175/a93167a3-336f-4a7c-b3fb-cc02bb7af1a4.png)

有効化すると、以下の画像のようにエージェントモードが選べるようになります。少しわかりづらいですが、画面下のリストから選択できます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/451175/813b13c1-711b-4e4d-bf0f-1666bc6dd4f6.png" width=60%>


#### 2. `settings.json` にMCP Serverの設定を追加
```json
  "mcp": {
    "servers": {
      "awslabs.aws-documentation-mcp-server": {
        "command": "/Users/{username}/.local/bin/uvx",
        "args": ["awslabs.aws-documentation-mcp-server@latest"],
        "env": {
          "FASTMCP_LOG_LEVEL": "ERROR"
        },
        "disabled": false,
        "autoApprove": []
      }
    }
  }
```

なお、1で設定したエージェントモードの有効化も `"chat.agent.enabled": true` を追記すれば設定できます。

:::note info
`command` は `uvx` へのフルパスを設定しています。
公式では`uvx`のみですが、パスが通らないこともあるためです。
:::

#### 3. MCP Server を実行

`settings.json`上に Start の文字が出るかと思うので実行します。成功すると `Running` が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/451175/254818ee-5554-455c-a439-b8b2c705c79c.png)


設定は以上になります。

## 使ってみる

Claude 3.7 Sonnetが東京リージョンで使えるか聞いてみます。2025/4/4 時点では利用不可です。

聞いてみると、以下のようにMCPサーバーが提供するツールを使って調べ始めます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/451175/140b1e86-6492-486f-9c59-42ee9f0ce60b.png" width=80%>

ツールを使う際にはユーザーへの確認が行われます。プルダウンから都度を確認しないよう設定できます。JSONでも`autoApprove`で設定することも可能に見えます。（ここは未検証）

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/451175/8d96d76a-a5c7-4339-95a6-427907ff58bd.png" width=80%>

最終的には以下のように正しい回答を出してくれました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/451175/9965428d-74b2-4144-a808-8cdbdba1bb12.png" width=80%>

## 何が嬉しいのか

[前回の記事](https://qiita.com/ny7760/items/3aa185c65889d66da0dc)を参照ください。

## 終わりに

簡単ですが、VS Code からAWS MCPを使った方法をご紹介しました。
MCP自体は Cline 等で既に利用していた人もいるかと思いますが、公式でサポートされるとさらにMCP Serverの利用・提供が増えそうですね。

この記事が誰かのお役に立てば幸いです。
真っ白なＷindowsPCにWSL2をインストールしていく

# WidowsPCで簡単にLinux仮想環境を構築する

コマンドメインで勉強したくその為の環境構築が面倒だったのでWSLを使ってみました。


<br>

まずはpowershellかコマンドプロンプトにて下記のコマンドを打ち込む。

PCはWindows11を使っています。
```
# WSLをインストール　デフォルトでWSL2がはいる
wsl --install
```
```
# Ubuntuをインストール
wsl --install -d Ubuntu
```
そしたら一旦シャットダウンして起動。

WSLを開くとユーザー名とパスワードが求められるので入力する。

あとは、sudo apt updateをしておくと尚良い。
```
# パッケージ情報を更新
sudo apt update
```

<br>

ここから先は番外編

<br>

私がやりたかったこと↓↓↓
```
# slコマンドをインストール
sudo apt install -y sl
```
```
# 実行🚃
sl
```
![スクリーンショット (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3982231/d6c020a3-62c4-4aa9-8892-560233c53876.png)

かわいい。。。。

<br>
<br>
学生時代はVirtualBoxでLinuxを動かしていましたが、WSLのほうが動作が速くて使いやすいです。ちょっとした作業だけならこっちの方がおすすめです。

めちゃくちゃ簡単なのでよければ使ってみてください。
【Python】～* を n 回出力、ただし w 個ごとに改行せよ～で見る効率化したコード例

## 🎯 お題：`*` を n 回出力、ただし w 個ごとに改行せよ

```python
n = int(input("nを何回にしますか?: "))
w = int(input("wをいくつにしますか?: "))
```

---

## 🙅‍♂️ 最初に書いたコード（Bad例）

```python
for i in range(n):
    print("*", end="")
    if i % w == w - 1:
        print()
if n % w:
    print()
```

### 🔍 問題点

- ループ回数：`n` 回（1文字ずつ出力）
- 条件分岐：`n + 1` 回（ループ内で毎回if判定＋最後にも1回）

→ 見た目が悪いわけじゃないけど、**処理としてはちょっと冗長**。

---

## ✅ 改善したコード（Good例）

```python
for _ in range(n // w):
    print("*" * w)
rest = n % w
if rest:
    print("*" * rest)
```

### 👍 改善ポイント

- ループ回数：`n // w` 回（まとめて出力）
- 条件分岐：1回だけ（余りがあるかどうか）

---

## 🧠 なぜこれが良いの？

- `print("*" * w)` のように、**繰り返しは計算に任せる**
- ループの中で毎回 `if` を書くのは、**無駄な処理を増やす原因**

---

## ✨ 実行例

n = 10, w = 3 のとき：

```
***
***
***
*
```

---

## 🎉 まとめ

| 項目 | Bad | Good |
|------|-----|------|
| ループ回数 | n回 | n // w回 |
| 条件分岐 | n+1回 | 1回 |
| 可読性 | 普通 | スッキリ！ |
| 処理効率 | やや遅い | 高速でスマート |
【AWS/Terraform】for_eachを使ったコードの書き方

## はじめに
terraformでAWSインフラを構築しようとしたとき，いろいろ調べると`for_each`を使うとコードの量の少なくて済むことに行きつくかと思います．　　
ただ，私が業務で`for_each`を使用していると実際に使うには勘所を抑える必要があると思ったので，まとめてみました．
これからterraformを使うエンジニアの方の助けになれば嬉しいです．

## for_eachの記法
`for_each`は要はループ処理です．私の個人的な解釈ですが，`for_each`はプログラミング言語（Python）でいう`while len(num)`に近いものだと思います．入力の中身の最後まで繰り返し処理するイメージです（伝われ）．
VPCの作成を例とすると下記のように書けます．
### set(string)を入力とした場合
~~~terraform
locals{
  param = toset(["vpc-a", "vpc-b"])
}
resource "aws_vpc" "vpc" {
  for_each = local.param
  
  cidr_block = "10.0.0.0/16"
  tags = {
    name = each.value
  }
}
~~~
ここで入力がset(string)の時限定で，`name = each.value`は`name = each.key`とも書けます．set(string)は要は配列なので`key`=`value`の概念がないためどちらでもよいのです．大体の場合は`value`に設定値を書くので，コード全体で統一するために`each.value`を書くことが多いです．
上記を実行すると以下の2つのVPCが作成されます．
- CIDR`10.0.0.0/16`の`vpc-a`
- CIDR`10.0.0.0/16`の`vpc-b`

つまり，同じset(string)を入力とした`for_each`は同じパラメータのリソースを複数作成する場合に適しているといえます．

:::note info
Tips
同じ設定値のリソースを複数作成したい場合等は，`set(string)`を入力として`for_each`に渡すと作りやすい
:::

しかし実際は2つのVPCに同じCIDRを使うのではなく，別のCIDRかつ名前も変えたいというシーンが多いのではないかと思います．
そんな時に使えるのがmap型を使用した作り方です．

### mapを入力とした場合①

~~~terraform
locals{
  param = tomap({
    vpc-a = {
      # vpc-aのパラメータをkey=value形式で書く 
      cidr = "10.0.0.0/16"
    },
    vpc-b = {
      # vpc-bのパラメータをkey=value形式で書く 
      cidr = "10.1.0.0/16"
    }
  })
}
resource "aws_vpc" "vpc" {
  for_each = local.param
  
  cidr_block = each.value.cidr
  tags = {
    name = each.key
  }
}
~~~
上記を実行すると以下の2つのVPCが作成されます．
- CIDR`10.0.0.0/16`の`vpc-a`
- CIDR`10.1.0.0/16`の`vpc-b`

このようにmapを入力に使用することで個々に設定値が異なるリソースを複数作成することができます．
肝心のリソースセクションはコードの中に一つのためコード全体が短くなりやすくなり，個々のリソースの設定値は`local` or `variable`の中に集約できるため保守性も高くなります．

:::note info
Tips
異なる設定値のリソースを複数作成したい場合等は，`map`を入力として`for_each`に渡すと作りやすい
:::

コードの中では`each.value`で統一した方がいいと言っているのに`each.key`を使用しているじゃないか！！
という ~~几帳面~~ 完璧主義の方向けに以下の書き方を紹介します．

### mapを入力とした場合②
~~~terraform
locals{
  param = [
    {
      name = "vpc-a"
      cidr = "10.0.0.0/16"
    },
    {
      name = "vpc-b"
      cidr = "10.1.0.0/16"
    }
  ]
}
resource "aws_vpc" "vpc" {
  for_each = {for i in local.param : i.name => i}
  
  cidr_block = each.value.cidr
  tags = {
    name = each.value.name
  }
}
~~~

作成されるリソースは"mapを入力とした場合①"の時と同じですが
`for_each = {for i in local.param : i.name => i}`
ここが難読だと思います．
ここで何が起きているのかというと，`for_each`が読み込める形式の`object`に変換しているのです．
今までの`for_each = local.param`では，すでに`for_each`が読み込める形式であったため変換は必要ありませんでした．
今回の`local.param`をよく見ると`key`がないんです．だから変換してあげる必要があります．
1. `:`の前`for i in local.param`
  →`local.param`の値を変数`i`に格納します
2. `:`の後`i.name => i`
  →`i.name`をkey, `i`をvalueとして変換
その結果以下のような`object`が内部的に出来上がります．
```
{
  "vpc-a" = {
      name = "vpc-a"
      cidr = "10.0.0.0/16"
  },
  "vpc-b" = {
      name = "vpc-b"
      cidr = "10.1.0.0/16"
  }
}
```
なんかみたことありますね．
そう！[mapを入力とした場合①](#mapを入力とした場合①)で紹介した書き方と同じです．ここではその変換をしているんですね．
こんな書き方もあるよと覚えておくといつか助かることがあるかもしれません．

:::note info
Tips
`{for i in local.param : i.name => i}`は`for_each`で使える形に変換している！
:::

# まとめ
`for_each`をうまく使うことでコードサイズの削減，保守性の向上が見込めます．
はじめのうちは慣れない記法でてこずるかもしれませんが，使いこなせるとコードの可読性がグン！と上がるのでぜひ積極的に使うようにしてみてはいかがでしょうか？
3元連立一次方程式の問題をランダムに出すサイトを作りました

# こちらです。
https://migawariw.github.io/3_variable_linear_equation/

python コードを ChatGPT を使ってjsに翻訳して作りました。

3文字の普通の連立方程式をたくさん解ける問題集がなかったので作りました。

# 仕様
解はどれも-10以上10以下の整数値です。

「連立方程式を生成」を押したときの時刻が記録され、「解を表示する」を押すと解答とともに押すまでにかかった時間が表示されます。

生成された問題が簡単すぎて気に入らなければもう一度「連立方程式を生成」を押してください。
新しい問題が表示され、時間もリセットされます。

線形従属なものは出てこないようになっている（ようにしたつもりである）ので、出された方程式の解は存在します。
個人的備忘録：Goの勉強会で学んだ「switch文」の使い方について体系的にまとめてみた

## はじめに
Go言語のswitch文は、条件に応じた処理の分岐を簡潔に記述できる構文です。

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

他の言語とは少し異なる特徴があり、使いこなすことでコードの可読性が高まります。

## 書こうと思ったきっかけ
受講しているITスクールでGoの勉強会が開催されていて、そこで学んだ内容を整理・復習するためにまとめています。

## switch文の基本構文
```go
switch 式 {
case 値1:
    // 処理1
case 値2:
    // 処理2
default:
    // どのcaseにも該当しない場合の処理
}
```

### 例：
```go
package main

import "fmt"

func main() {
    day := "Monday"

    switch day {
    case "Monday":
        fmt.Println("週の始まりです")
    case "Friday":
        fmt.Println("もうすぐ週末です")
    default:
        fmt.Println("通常営業日です")
    }
}
```

## 特徴とポイント
- break が不要（caseが実行されると自動的に抜ける）
- 複数のcaseに同じ処理を書くことができる（カンマ区切り）
- switch 式がなくても条件分岐できる（if-elseのような使い方）

### 式なしswitch（if-else代替）：
```go
switch {
case age < 13:
    fmt.Println("子供です")
case age < 20:
    fmt.Println("ティーンエイジャーです")
default:
    fmt.Println("大人です")
}
```

## まとめ
Goのswitch文は、冗長なif-elseを避けつつ、複雑な条件分岐を整理するのに適しています。特にbreak不要、式省略可能といったGo独自の仕様を理解しておくことで、よりスッキリとしたコードが書けるようになります！
個人的備忘録：Goの勉強会で学んだ「:=」の使い方について体系的にまとめてみた

## はじめに
Go言語では、変数宣言と初期化を同時に行うことができる「セイウチ演算子（:=）」が用意されています。

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

シンプルな構文でコードの可読性を高める便利な機能です。

## 書こうと思ったきっかけ
受講しているITスクールでGoの勉強会が開催されていて、そこで学んだ内容を整理・復習するためにまとめています。

## セイウチ演算子（:=）とは？
- Goで新しい変数を宣言するときに使用する短縮記法です。
- 型の指定は不要で、右辺の値に応じて自動的に型推論されます。

### 例：
```go
package main

import "fmt"

func main() {
    x := 10
    y := "Hello"
    fmt.Println(x, y)
}
```

上記のコードは、以下と同等です：
```go
var x int = 10
var y string = "Hello"
```

## 特徴と注意点
- 初回宣言時にのみ使用可能（すでに定義された変数には使用できない）
- 関数のスコープ内でよく使われる
- 変数の再宣言はできない（ただし、一部の新規変数と一緒に使うことは可能）

### 再宣言NGな例：
```go
x := 5
x := 10 // エラー：x はすでに宣言済み
```

### 一部新規ならOK：
```go
x := 5
y := 6
x, y = 10, 20         // 再代入はOK
x, z := 30, 40         // zが新規なのでOK
```

## まとめ
Goのセイウチ演算子は、変数宣言と初期化を簡潔に書ける便利な機能です。初学者でも読み書きしやすく、スコープの理解にもつながります。

***勉強会で実践した例をもとに、今後も積極的に活用していきたいです！***
Macでメモリの多いモデル

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90217/d4a10f11-72dc-4783-be04-0b969277e2d3.png)

## 64GB なら Mac mini M4 Proモデル 308,800円

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90217/aa1d6a0f-48b6-40e7-a5c4-18f6a2b47462.png)

## 128GB なら Mac Studio M4 Maxモデル 583,800円

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90217/75e53f48-46e9-4cf2-83b8-057acf8236b3.png)

## 256GB なら Mac Studio M3 Ultraモデル 908,800円

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90217/07d6a6b3-a0d5-4ab7-a2a9-3826a506e278.png)

## 512GB なら Mac Studio M3 Ultraモデル 1,493,800円

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90217/72b8cff3-c866-4a11-b186-3c62087ca2db.png)

ローカルAI、RAM 512GBあるとサクサクらしいです。
GPTとLLMの仕組みがわかるサイトを見つけた(日記)


ネットサーフィンしていたら、LLMの仕組みがわかるサイトを見つけた。

https://x.com/taiyo_ai_gakuse/status/1907760869339172978


https://bbycroft.net/llm



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4046871/76fceb27-a662-44c5-8c47-f01c0a356ca6.png)






## 長文読解：GPTのしくみ ― 小さなAIの大きな旅(GPTに書かせた)
今、目の前にあるのは「C B A B B C」という6つの文字列です。これは、私たちが使うAIモデルにとっての冒険の始まりです。この文字列を、AIに渡して並び替えてもらいましょう。目指すゴールは「A B B B C C」というアルファベット順の並び。さて、小さなGPTモデル、通称「nano-GPT」はどのようにしてこれを成し遂げるのでしょうか？

まず、文字たちはトークンと呼ばれる単位に変換されます。Aは0、Bは1、Cは2というふうに数値化され、AIの世界で通じる「言葉」となります。つまり「C B A B B C」は「2 1 0 1 1 2」となります。

Embedding（埋め込み層）
しかし、数字の羅列だけでは、AIはそれらの意味を理解できません。そこで最初に行われるのが**Embedding（埋め込み）**です。この処理では、各トークンが48次元のベクトルに変換されます。たとえば「2（C）」は [−0.7, 0.4, 0.8, ...] のようなベクトルへと変化します。このベクトルは、文字の意味や文中での役割を数値的に表現したものであり、まるで文字に魂を宿すようなプロセスです。

Layer Norm（レイヤー正規化）
次に、これらのベクトルは**Layer Normalization（レイヤーノーム）**を受けます。これは、入力のスケールや偏りを整える工程で、人間で言えば気持ちを落ち着かせる深呼吸のようなものです。これにより、次のステップでの学習が安定しやすくなります。

Self Attention（自己注意機構）
ここからがモデルの知性が光る部分です。**Self-Attention（自己注意）では、各トークンが「自分は誰に注目すべきか？」を判断します。たとえば、ある「B」が「この前に現れたAが重要だ」と気づくことで、文脈を理解していきます。この処理ではクエリ（Query）・キー（Key）・バリュー（Value）**という3つのベクトルを使い、トークン同士の関係性を計算します。これはまるで、会話の中で「誰が何を言ったかを覚えている」ような働きです。

Projection（投影層）
Attentionによって得られた情報は、そのままでは使いにくいため、**Projection（投影）**層で再び変換されます。これは線形変換と呼ばれ、ベクトルの形を整えて、次の層で利用しやすい形にします。

MLP（多層パーセプトロン）
整えられたベクトルは、次に**MLP（多層パーセプトロン）**という全結合ニューラルネットワークに渡されます。ここでは非線形な変換が行われ、モデルはさらに複雑なパターンを学習することができます。まるで、経験を積むことで物事の本質を理解していくような成長のステージです。

Transformer（変換の層）
これらすべての処理（Self-Attention + MLP）をまとめてTransformer層と呼びます。実際のGPTでは、これらの層が何層も重なっています。層を重ねることで、より深い文脈や意味を捉えられるようになり、モデルの理解力が増していくのです。

Softmax（確率化）
さて、すべての処理を終えたベクトルは、最終的にSoftmax関数を通して、確率に変換されます。「次に来る文字はAが70%、Bが20%、Cが10%の確率である」といった形で、モデルの「予測」が数値として現れるのです。

Output（出力）
そして、最も高い確率のトークンが**Output（出力）として選ばれます。たとえば「A」が最も高ければ、それが次の文字となります。この出力は次の入力としてモデルに再び与えられ、次のトークンの予測が始まります。この一連の流れを自己回帰的生成（autoregressive generation）**と呼びます。

このように、わずか6つの文字列を処理するだけでも、GPTの中では多くの高度な計算と「注意」と「変換」が行われています。そしてこの小さなモデルの動作原理は、数十億のパラメータを持つ大型GPTでも基本的に同じです。大きなAIの心の中も、実は小さな仕組みの積み重ねでできているのです。







あー、なるほどー。。。。
AWS認定ソリューションアーキテクト アソシエイト (SAA) ：AWSインフラストラクチャの基礎

## はじめに

AWS認定ソリューションアーキテクト アソシエイト (SAA) の資格取得を目指しています。この記事では、AWS初心者の私がAWSの基本的なインフラストラクチャについて学んだ内容をまとめました。

## AWSとは

AWS（Amazon Web Services）は、Amazonが提供するクラウドコンピューティングサービスの総称です。

### AWSの主な特徴
- **クラウドコンピューティングプラットフォーム**: 物理的なハードウェアを購入・管理する代わりに、必要なITリソースをインターネット経由でレンタルできる
- **200以上のサービス**: コンピューティング、ストレージ、データベース、ネットワーキングなど多岐にわたる
- **従量課金制**: 使用した分だけ支払うモデル（資本支出から運用支出へのシフト）

### AWSの主要なメリット
- **俊敏性**: 数分でサービスをデプロイ可能
- **弾力性**: 需要に応じてリソースを自動的に拡張・縮小
- **コスト効率**: 初期投資不要、使った分だけ支払い
- **グローバル展開**: 世界中の複数リージョンにデータセンターを持つ

## AWSのグローバルインフラストラクチャ

AWS認定試験では、AWSのグローバルインフラストラクチャの理解が重要です。これには、リージョン、アベイラビリティゾーン、エッジロケーションという3つの主要な構成要素があります。

### リージョン

[AWSリージョン]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3461603/557608da-2c86-4867-a082-659ec846ab98.png)


**役割**: データとサービスを保存・実行する主要な場所

**特徴**:
- 地理的に独立した区域で、複数のデータセンターの集まり
- 世界中に分散（アメリカ、ヨーロッパ、アジア、アフリカなど）
- 各リージョンは完全に独立している（データやサービスは自動的に他のリージョンにレプリケートされない）
- 「us-east-1」（バージニア）、「ap-northeast-1」（東京）などの形式で表記

**例え**: リージョンは大きなショッピングモールのようなものです。それぞれの街（世界の各地域）に独自のショッピングモールがあります。東京モール、ニューヨークモール、ロンドンモールなど。あなたは自分のお店（アプリケーション）をどのモールに出すか選べます。

**選択基準**: レイテンシー、コスト、コンプライアンス要件、利用可能なサービス

### アベイラビリティゾーン (AZ)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3461603/630717e8-d088-49f2-ad40-4a46de03cfb9.png)
例えば、東京リージョンに4つのアベイラビリティゾーンがある

**役割**: 一つのリージョン内での障害対策

**特徴**:
- 各リージョン内の独立したデータセンター群
- 物理的に分離された施設（数キロ〜数十キロ離れている）
- 独立した電源、ネットワーク、冷却設備
- 高速・低レイテンシーのネットワークで相互接続
- 「us-east-1a」のように、リージョンコード+アルファベットで表記

**例え**: 各ショッピングモール（リージョン）には複数の建物（AZ）があります。もし一つの建物で火事が起きても、他の建物は無事なので、ビジネスを続けられます。賢い店主は複数の建物に同じ店を出して、どこか一つが問題になっても営業できるようにします。

**意義**: 1つのAZが障害を起こしても、他のAZは影響を受けない設計（災害対策）

**ベストプラクティス**: マルチAZデプロイメントによる高可用性の実現

### エッジロケーション


**役割**: コンテンツを高速に配信する

**特徴**:
- AWSのCDN（コンテンツ配信ネットワーク）であるCloudFrontのための拠点
- リージョンよりも多く、世界中の主要都市に配置
- エンドユーザーに近い場所からコンテンツを配信
- キャッシュされたコンテンツを提供し、オリジンサーバーへのトラフィックを減少

**例え**: エッジロケーションは、モール（リージョン）の商品を売る小さな出張所のようなものです。例えば、人気の商品をすべての地域の住宅街の近くに置く小さな販売所を作れば、お客さんはわざわざ遠くのモールまで行かなくても買い物ができます。これにより、速くサービスを受けられます。

**主な用途**:
- CloudFrontによるコンテンツ配信の高速化
- Route 53（DNSサービス）のDNSクエリ応答
- AWS Shield（DDoS保護）の最前線
- Lambda@Edgeの実行

## 実際の使い方

AWSの各インフラストラクチャ要素は、以下のように活用されます：

1. **アプリケーションのメインサーバー**はリージョンに置きます
2. **障害対策**として、同じリージョン内の複数のAZにサーバーを配置します
3. **世界中のユーザーに速くコンテンツを届けたい場合**は、エッジロケーションを活用します

## SAA試験に向けて

AWS認定ソリューションアーキテクト アソシエイト試験では、これらのインフラ要素を理解し、高可用性・耐障害性のあるアーキテクチャをどう設計するかが問われます。特に、マルチAZデプロイメントの概念と、リージョン間レプリケーションの使い分けは重要です。

## 次のステップ

インフラストラクチャの基本を理解したら、次のステップとして以下のトピックを学習するとよいでしょう：

1. **主要なAWSサービス**：EC2（仮想サーバー）、S3（ストレージ）、RDS（データベース）など
2. **ネットワーキング**：VPC（仮想プライベートクラウド）、サブネット、セキュリティグループ
3. **アイデンティティとアクセス管理**：IAM（ユーザー、グループ、ロール、ポリシー）

## まとめ

AWSのグローバルインフラストラクチャは、リージョン、アベイラビリティゾーン、エッジロケーションの3つの主要な要素で構成されています。これらを適切に活用することで、高可用性、耐障害性、低レイテンシーのアーキテクチャを設計することができます。

AWS認定ソリューションアーキテクト アソシエイト試験に向けて、これらの基本的な概念をしっかりと理解しておきましょう。

---

参考資料：
- [AWS グローバルインフラストラクチャ](https://aws.amazon.com/jp/about-aws/global-infrastructure/)
- [AWS ドキュメント](https://docs.aws.amazon.com/ja_jp/index.html)
Figmaデザイン前の準備作業

## はじめに
ワイヤーフレームの作成のためにFigmaを使いました。
この記事では、基本操作を簡単にまとめ、初心者の方でもわかりやすいように解説します。

### 実施すること
ワイヤーフレームを作成するにあたり、以下の準備作業を行います
- フレームで土台を作る
- グリッドを利用して補助線を引く
- グリッドに制約を設定する（土台フレームのサイズを変更した際にグリッドも追従させる）

## フレーム
Figmaのフレームは、デザイン作業の基盤となる枠組みとなります。  
この上にコンテンツやUIパーツを配置していきます。  
PhotoshopやIllustratorでいうアートボードですね。  

### 作成方法
- ショートカットキー`F`を押して、フレームテンプレートを表示します。
- 表示された中から対象デバイスを選んで追加します。
- キャンバス上にドラッグすることで任意のサイズで作成することもできます。

![スクリーンショット 2025-04-04 202959.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1518953/4c248014-c318-4214-b466-688fa5341171.png)

## グリッド
グリッドを利用すると、パーツを配置する際に整列が簡単になり、統一感のあるデザインが作れます。

### 作成方法
1. フレームを作る
2. フレームのサイズをデバイスサイズに揃える
   - フレームの端をドラッグし、対象フレームに近づけることで揃えることができる
3.  レイアウトグリッドの`+`を押下する
    ![スクリーンショット 2025-04-04 205718.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1518953/d976fe33-75c5-44cb-a6c2-5b8e4845c927.png)
4. サイズを`8`に変更する

### なぜグリッドのサイズを8にするのか？
一貫性のあるデザインを作成するために、4の倍数や8の倍数でUIデザインを行う手法があります。  
これは`4ポイントグリッドシステム`呼ばれる考え方だそうです。  

以下の理由で推奨されています。
- 一般的なデバイスサイズは4か8で割り切ることが可能(例: 1920px×1080px、 1280px×720px)
- 要素を均等に配置しやすく、一貫性が生まれる
- スケーリングの容易さ: 例えば1.5倍で拡大・縮小を行っても、割り切れるためレイアウトが崩れない

https://medium.com/@aratidube12lns/4-point-grid-system-for-more-consistent-interface-design-efea81dea3f3

## 制約（Constraints）
デバイスサイズを変更したいとき、先ほど作成したグリッドのサイズも変更しないといけません。
そこで制約を指定しておくと、親要素を変更すると子要素も追従しサイズを揃えることが可能となります。

### 設定手順
1. サイズを追従させたい子要素を選択する
2. 右側のパネルから制約アイコンをクリックする
    ![スクリーンショット 2025-04-04 235554.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1518953/957a61ab-7d3d-4d72-a7f6-d4e496bd3066.png)
3. 追従させたい方向を選択する
  ![スクリーンショット 2025-04-04 235940.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1518953/8f9e89a2-d090-4e77-8cec-36142e733921.png)

これにより、指定した方向に沿って親要素がサイズ変更された際、子要素も自動的に揃えられるようになります。

## 参考文献
https://note.com/fujisaki_neko/n/n81043403659f#ad605437-16ec-43e4-8456-74be9d5c19a8

https://medium.com/design-bootcamp/the-4-point-grid-system-in-ux-e21f5573e5e8

https://medium.com/@aratidube12lns/4-point-grid-system-for-more-consistent-interface-design-efea81dea3f3

https://www.figma.com/community/file/1228577958737472070
プリザンターの添付ファイルをダウンロードする便利ツール

## はじめに
プリザンターの添付ファイルをサイト単位で一括ダウンロードするツールを作成したので紹介します。添付ファイル項目だけではなく、内容・説明・コメントに貼り付けられている画像のダウンロードにも対応しています。

:::note info
2025/04/07に添付ファイル項目以外にファイルの貼り付けが可能なv1.0.1をリリースしました。このページの内容はそれに準じて編集をしています。v1.0.0をお持ちの場合はv1.0.1以降に更新して使用してください。
:::

## 主な使用目的
添付ファイル項目のバックアップなどファイルの実体をまとめて用意する必要があるケースを想定しています。
プリザンターの添付ファイルの保存方法には、

* Database：データベースにBASE64化して保存する方法
* Local：データベースにメタデータを、実体はバイナリデータをファイルに格納しファイルシステムに保存する方法

の2つがあります。`Database`の場合はデータベースの`Binaries`テーブルの中のBASE64文字列を操作する必要が、`Local`の場合はファイル名がGUIDに変換されているためデータベースを参照してファイル名を探す必要が、と、いずれも面倒な操作が必要になります。
このツールを使用することで、それらの操作を一切必要とせず、サイトIDを指定するだけでサイト単位にファイルをまとめてダウンロードすることがきます。

## 使い方
.NET 8がインストールされている環境であればWindowsに限らず、MacOSやLinux環境などでも動作します。プリザンターのVer. 1.4.*系が動作する環境であれば問題無く動作します。

コマンドラインでの実行となります。

```bat
dotnet pleasanter-items-attachments-downloader.dll /Url:{URL} /SiteId:{SiteId} /ApiKey:{APIキー} /Path:{出力先} [/Skip:{除外する項目}] [/Target:{包含する項目}]
```

|パラメータ|説明|
|--|--|
|/Url|プリザンターの動作している環境を指すURLを指定します。サブディレクトリ環境で運用している場合はサブディレクトリまで指定してください。|
|/SiteId|サイトIDを指定します。|
|/ApiKey|APIキーを指定します。サイトIDに指定したサイトに対して「読取り」「サイトの管理」の2つの権限が必要になります。|
|/Path|出力先のパスを指定します。このパスは実在する必要があります。|
|/Skip[^パラメータ併用不可]|除外する項目をAttachmentsAなどの物理名を指定します。添付ファイルA、説明Cなどと複数の項目を指定する場合は、カンマ区切りで連結してください。（例：`AttachmentsA,DescriptionC`）Community Editionだけではなく、Enterprise Editionの拡張項目001～100にも対応しています。|
|/Target[^パラメータ併用不可]|包含する項目をAttachmentsAなどの物理名を指定します。添付ファイルA、説明Cなどと複数の項目を指定する場合は、カンマ区切りで連結してください。（例：`AttachmentsA,DescriptionC`）Community Editionだけではなく、Enterprise Editionの拡張項目001～100にも対応しています。|

同じパスに同じサイトで複数回実行した場合は、ダウンロード済みのファイルは上書きされます。一方的にダウンロードするだけなので、プリザンター側で削除されていたとしても、ローカル側のファイルの削除は行われません。

また、例外処理がかなり大雑把なので、何か1つの処理が失敗すると以降の処理が打ち切られます。例外内容については画面に出力されるので、そちらを参考にトラブルシュートしてください。GitHub(後述)でIssueを上げてもらえれば、対応出来る範囲では対応します。

## 実際の動き
実行すると指定したパスの配下に次の様な構造でファイルを出力します。

```plantuml
@startsalt
{
{T
 + [Path]
 ++ [SiteId]サイト名
 +++ [ResultId/IssueId]レコードタイトル
 ++++ [添付ファイル項目物理名]添付ファイル項目論理名
 +++++ [添付ファイルID]添付ファイル名
}
}
@endsalt
```
実際の出力をTreeコマンドでみると次の様になります。
```
E:\Temp
└─[3526345]記録テーブル(子テーブル)
    └─[3528504]ううううう - コピー)12 - コピー - copy - copy
        └─[AttachmentsA]
                [111455]log174_2503170830.xlsx
                [111456]log174_2503170830.csv
                [111457]log000_2503180830.csv
```

## ダウンロード
GitHubの[Pleasanter Developer Community](https://github.com/pleasanter-developer-community)でソースコードごと公開しています。ライセンスはMIT Licenseなので、ご自由にご使用ください。
[pleasanter-items-attachments-downloader](https://github.com/pleasanter-developer-community/pleasanter-items-attachments-downloader)がプロジェクトになります。Releaseから最新リリース分のバイナリがダウンロード出来ます。

## まとめ
今回はプリザンターから添付ファイルをまとめてダウンロードしてくるツールを紹介しました。使い方はアイデア次第なところがありますので、是非使ってみてください。

[^パラメータ併用不可]:/Skipと/Targetは併用出来ません。
swiftのスレッドを擬人化

:::note
間違いあれば指摘していただけると助かります。
:::

### 例えば

```swift:
print("A")

DispatchQueue.global().async {
    // 重い処理
    let result = heavyCalculation()

    DispatchQueue.main.async {
        // 結果をUIに反映
        updateLabel(with: result)
    }
}

print("C")
```
### 会話
1. メインさん：「Aって表示しとくで〜」
1. バックグラウンドさん：「重い計算？おう、まかせといてや！終わったらメインさんに言うわ」
1. メインさん：「Cもとりあえず表示しとこか〜」

（数秒後）

4\. バックグラウンドさん：「終わったで！メインさん、表示頼むわ！」
5. メインさん：「おっしゃ、ラベル更新しとくわ！」

## 非同期処理と同期処理
同期：前の処理が終わるまで待つ
非同期：全ての処理が終わってから実行

![名称未設定ファイル.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3770358/1dd8a9ae-0e56-4147-9eec-8f1500e5bc0d.png)
Streamlitでアプリ作成① ~ChatGPTでのデータ可視化の簡易実装～

# はじめに
仕事で簡単な分析をする際に、いちいちコード書いて分析するのが面倒なので、Streamlitというライブラリを用いて少しずつアプリ開発をしていこうと思う。

# 実装した機能
今回はStreamlitでどのようなことができるのかを知りたかったので、ChatGPTに「アンケートデータを簡単に可視化できるようなアプリを作って」という依頼をし、出てきたコードをそのまま実行した。
コード内で実装した機能は以下である。
①csvデータのアップロード
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2877638/09054393-779e-4f33-95d3-4c66cd720dde.png)
②データのプレビュー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2877638/9d1a4498-ef06-4bb2-b3ed-75ebcbf06b87.png)
③グラフ（ヒストグラム/棒グラフ/折れ線グラフ）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2877638/b6cc463c-c895-44ec-9688-fcc762af5288.png)
④散布図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2877638/65765291-1116-432f-84c1-a2c232ed4509.png)
⑤ヒートマップ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2877638/e74bdc25-e58b-4b3f-9f9c-21714617852b.png)

# 実装したコード
```python
import streamlit as st
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

st.title("データ可視化")

uploaded_file = st.file_uploader("CSVファイルをアップロードしてください", type="csv")

if uploaded_file:
    df = pd.read_csv(uploaded_file)

    st.subheader("データのプレビュー")
    st.dataframe(df)

    # 数値型カラムだけ抽出
    numeric_cols = df.select_dtypes(include='number').columns.tolist()

    st.subheader("グラフ")
    col1 = st.selectbox("カラムの選択", numeric_cols)
    chart_type = st.radio("グラフの種類", ['ヒストグラム', '棒グラフ', '折れ線グラフ'])

    if chart_type == 'ヒストグラム':
        fig1 = sns.histplot(df[col1], kde=True).figure
        st.pyplot(fig1)
    elif chart_type == '棒グラフ':
        fig2 = sns.countplot(x=col1, data=df).figure
        st.pyplot(fig2)
    elif chart_type == '折れ線グラフ':
        st.line_chart(df[col1])

    st.subheader("散布図")
    x_var = st.selectbox("X軸を選択", numeric_cols, key="x_var")
    y_var = st.selectbox("Y軸を選択", numeric_cols, key="y_var")

    if x_var and y_var:
        fig3, ax3 = plt.subplots()
        sns.scatterplot(x=df[x_var], y=df[y_var], hue=df.get("性別"), ax=ax3)
        st.pyplot(fig3)

    st.subheader("ヒートマップ")
    corr = df[numeric_cols].corr()
    fig4, ax4 = plt.subplots()
    sns.heatmap(corr, annot=True, cmap="coolwarm", ax=ax4)
    st.pyplot(fig4)

else:
    st.info("まずはCSVファイルをアップロードしてください。")
```

# 感想
Streamlitへの分析結果の渡し方は理解しないといけなさそうだが、簡単にwebアプリが実装できると分かってよかった。データ可視化はデータビジュアライゼーションに関する本なども参考にしながら、アップデートしていこうと思う。次回は、ビジュアライゼーションについて書くと思う。（多分）
ヘッダーを固定しよう

# ヘッダーを固定する
Webアプリでヘッダーを固定しようと思います。

IEのときは苦戦しましたが、Edgeでは
position: sticky;
が使えます。

いつも使う頃に忘れているので、サンプルコード纏めておきます。

## サンプルその１
<p class="codepen" data-height="600" data-default-tab="result" data-slug-hash="NPWLXbO" data-pen-title="Untitled" data-user="cjlsrdxi-the-builder" style="height: 600px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/cjlsrdxi-the-builder/pen/NPWLXbO">
  Untitled</a> by masayasu_t (<a href="https://codepen.io/cjlsrdxi-the-builder">@cjlsrdxi-the-builder</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://public.codepenassets.com/embed/index.js"></script>

タイトルだけだとつまらないので、サブタイトルも固定しています。
htmlでは下に書かれた要素が前方に来るため、z-indexを指定しないとサブタイトルがタイトルの上に来ます。

## サンプルその２
<p class="codepen" data-height="600" data-default-tab="result" data-slug-hash="RNwdoOj" data-pen-title="Untitled" data-user="cjlsrdxi-the-builder" style="height: 600px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/cjlsrdxi-the-builder/pen/RNwdoOj">
  Untitled</a> by masayasu_t (<a href="https://codepen.io/cjlsrdxi-the-builder">@cjlsrdxi-the-builder</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://public.codepenassets.com/embed/index.js"></script>

テーブルで縦横のヘッダー、フッターを固定しています。
罫線がきれいになるように線を描画する側のセルを意識しています。
重複単語をスマートに処理！Setで処理を速く！

paizaの重複単語の問題を解いた！直感で`includes()`を使って書いたけど、データ量が大きくなったら`Set`の方が確実に計算が速くて良さそう！

## <br>問題概要

入力されたスペース区切りの単語を、1行ずつ出力。ただし、同じ単語が2回目以降に出てきたら `already_been` に置き換える。

<br>入力:
```
red green blue blue green blue  
```
出力:
```
red  
green  
blue  
already_been  
already_been  
already_been  
```

https://paiza.jp/works/mondai/c_rank_skillcheck_archive/word-count_03

## <br>例: includes() を使うと O(N²) の悲劇
なんとなくで初めに書いたやつ
```js
const words = input.split(' ');
const seen = []; // 既出単語を保存する配列

words.forEach(word => {
    if (!seen.includes(word)) {  // O(N) の検索
        console.log(word);
        seen.push(word);  // 配列に追加
    } else {
        console.log("already_been");
    }
});
```
🔴 問題点:
	•	`includes()` は O(N) で検索 → ループ内で使うと O(N²) に！
	•	N が 10万 のとき、最悪 10億回の比較…


## <br>例: Set で O(1) 検索 & O(N) ループ
```js
const words = input.split(' ');
const seen = new Set(); // 既出単語を保存する Set

words.forEach(word => {
    if (seen.has(word)) {  // O(1) の検索
        console.log("already_been");
    } else {
        console.log(word);
        seen.add(word);  // Set に追加
    }
});
```
✅ 改善点:
	•	`Set` の `has()` は O(1) だから、ループ全体で O(N) で完了！
	•	大量データ（N ≒ 10万）でも 爆速処理！

## <br>Set が便利な理由まとめ

✔ `Set` の `.has()` は O(1) で超高速
　　→（配列の `includes()` は O(N)）
✔ 重複なしのデータ管理に最適（余計なデータを増やさない）
✔ パフォーマンス重視なら `Set` 一択！（特に大規模データ）

→ `includes()` は小規模ならOK、大量データなら `Set` で最適化しよう！

<br>[🔗僕の失敗談と解決話！](https://paizabeginner.wordpress.com/2025/04/04/paiza%e3%81%a7%e5%9f%ba%e6%9c%ac%e3%83%9e%e3%82%b9%e3%82%bf%e3%83%bc-%e9%87%8d%e8%a4%87%e5%8d%98%e8%aa%9e%e3%82%92%e3%82%b9%e3%83%9e%e3%83%bc%e3%83%88%e3%81%ab%e5%87%a6%e7%90%86%ef%bc%81set%e3%81%a7/)
SQL #3【LIKE / IN / DISTINCT / ORDER BY / LIMIT / OFFSET】

## はじめに
こちらの**Membersテーブル**を使用します。
|id|name|age|home|
|---|---|---|---|
|1|Yamamoto|20|Tokyo|
|2|Sato|25|Osaka|
|3|Yamada|16|Tokyo|
|4|Tanaka|35|Nagoya|
|5|Kato|42|Osaka|

## LIKE
**大文字小文字を区別しない**文字列検索を行う
```sql
SELECT * FROM テーブル名 WHERE カラム名 LIKE "パターン";
```

### ワイルドカード検索（部分一致）
| ワイルドカード文字 | 意味 |　例  |
|:-:|:-:|:-:|
| % | 0文字以上の任意の文字列 |"A%" → Aで始まる|
| _ | 任意の1文字 |"A_" → Aの後に1文字続く|

### Yamaで始まるメンバーを取得する
```sql
SELECT * FROM Members WHERE name LIKE "Yama%";
```
|id|name|age|home|
|---|---|---|---|
|1|Yamamoto|20|Tokyo|
|3|Yamada|16|Tokyo|

## IN
- 指定した値の中に該当するデータを取得する
- 戻り値の型は **Boolean**
```sql
SELECT * FROM テーブル名 WHERE カラム名 IN (値1, 値2, 値3, ...);
```

### 年齢が25歳と35歳のメンバーを取得する
```sql
SELECT * FROM Members WHERE age IN (25, 35);
```
|id|name|age|home|
|---|---|---|---|
|2|Sato|25|Osaka|
|4|Tanaka|35|Nagoya|

:::note alert
**NULL**の取り扱い
IN / NOT IN では NULL の抽出ができない。
NULL を抽出したい場合、IS NULL か IS NOT NULL を使用する。
:::

## DISTINCT
指定したカラムにおいて、重複データをまとめる
```sql
SELECT DISTINCT カラム名 FROM テーブル名;
```
### homeを重複なしで取得する
```sql
SELECT DISTINCT home FROM Members;
```
|home|
|---|
|Tokyo|
|Osaka|
|Nagoya|

## ORDER BY
- 抽出するデータを**並び替える**
- **ASC**（昇順、既定値）か **DESC** （降順）を末尾で指定する
- NULL は**最小値**として扱われる
```sql
SELECT * FROM テーブル名 ORDER BY カラム名 ASC/DESC
```
 ### 年齢の高い順で並べ替える
 ```sql
 SELECT * FROM Members ORDER BY age DESC;
 ```
|id|name|age|home|
|---|---|---|---|
|5|Kato|42|Osaka|
|4|Tanaka|35|Nagoya|
|2|Sato|25|Osaka|
|1|Yamamoto|20|Tokyo|
|3|Yamada|16|Tokyo|

## LIMIT
- クエリによる出力結果の行数を**制限**する
- **`ORDER BY`** と組み合わせることが多い
```sql
SELECT カラム名 FROM テーブル名 LIMIT 抽出する行数（整数）
```

### 年齢が若い順に2人のメンバーを取得する
```sql
SELECT * FROM Members ORDER BY age ASC LIMIT 2;
```
|id|name|age|home|
|---|---|---|---|
|3|Yamada|16|Tokyo|
|1|Yamamoto|20|Tokyo|

## OFFSET
- 指定した行数分だけ結果の表示を**スキップ**する
- **`LIMIT`**・**`ORDER BY`** と組み合わせることが多い

### 年齢が3.4番目に高いメンバーを取得する
```sql
SELECT * FROM Members ORDER BY age DESC LIMIT 2 OFFSET 2;
```
|id|name|age|home|
|---|---|---|---|
|2|Sato|25|Osaka|
|1|Yamamoto|20|Tokyo|

:::note warn
**LIMIT / OFFSET の注意点**
複雑なクエリやデータ量が大きい場合には非効率。
→ スキップされた行もすべて読み込まれて処理されるから。
:::

## まとめ
:::note info
- LIKE : 文字列検索（部分一致もOK）
- IN : 指定した値に該当するデータを取得
- DISTINCT : 重複をなくす
- ORDER BY : 並べ替え（昇順・降順）
- LIMIT : 抽出するデータを制限
- OFFSET : 指定した行数分のデータ表示をスキップ
:::

## 参考文献
https://learn.microsoft.com/ja-jp/azure/databricks/sql/language-manual/
Azureのサービスはバラバラにしか配置できないって前提で設計しろ

2025年4月よりAzureを触りだしたので、思ったことをつらつらと。


# Azureでリージョン跨ぎの仮想ネットワーク構成をするときに必ずハマるプライベートエンドポイント地獄

## はじめに

Azure構成でセキュアなネットワークを組もうとしたときに、意外と見落とされがちなのが「**サービスのリージョンがバラバラ問題**」と「**サービスエンドポイントが使えない問題**」。

この記事では、実際に自分がハマった経験をもとに、App Service, Cosmos DB, Azure AI Search, Azure OpenAI, Functionsなどを含む**リージョン跨ぎのVNet構成**で陥りやすい落とし穴とその回避法をまとめます。

---

## 構成概要

### 利用サービス：
- App Service（日本リージョン）
- Azure Cosmos DB（海外リージョン）
- Azure AI Search（海外リージョン）
- Azure OpenAI（海外リージョン）
- Azure Functions（Flexプラン、海外リージョン）

### 要件：
- すべてのサービスを仮想ネットワーク経由でセキュアに接続
- App ServiceとFunctionsはVNet統合
- その他のサービスはPrivate Endpointで閉域接続

---

## なぜプライベートエンドポイントが必須になるのか？

### 理由1：サービスエンドポイントは同一リージョンのみ
Azureの**サービスエンドポイントはリージョンをまたぐと機能しない**ため、日本リージョンのApp Serviceから海外リージョンのCosmos DBなどへは接続不可になります。

### 理由2：Azureはサービスごとに対応リージョンが異なる
- Azure OpenAIやFunctionsのFlexプランは日本リージョンに未対応（2025年現在）
- Cosmos DBやAI Searchも機能対応が地域によってバラバラ

したがって、**リージョン跨ぎが前提になる**ため、サービスエンドポイントではなく、**Private Endpoint + Private DNS**で接続する必要があるのです。

---

## プライベートエンドポイント構成の要点

### 1. Private Endpoint を各サービスに対して作成
- Cosmos DB、AI Search、OpenAI → それぞれのリージョンでPrivate Endpoint作成

### 2. Private DNSゾーンの作成とVNetへのリンク
- 各サービスに対応するPrivate DNSゾーンを作成
- 日本リージョンVNetと海外リージョンVNetの両方にリンク
- 名前解決の不整合を防ぐため、**手動でAレコード追加が必要な場合あり**

### 3. App Service / FunctionsのVNet統合
- App Service：従来通りRegional VNet IntegrationでOK
- Functions：**Flexプラン必須。従来の従量課金プランではVNet統合不可**

---

## SNATではなぜ代用できないのか？

### SNAT（Source NAT）の特徴：
- インターネット経由のアクセス（出るときにAzureの外部IPに変換）
- 出口制御が難しい、IPが不定、セキュリティに弱い

### 問題点：
- リージョン跨ぎではSNATでも接続できないサービスがある（CosmosやOpenAIなど）
- セキュリティグループやFirewallで許可できないケースが発生

### 結論：
> **セキュリティ、安定性、リージョン跨ぎすべてを満たすには、Private Endpoint一択！**

---

## 注意点まとめ

| 項目 | 内容 |
|------|------|
| サービスエンドポイント | リージョン跨ぎでは使えない |
| プライベートDNS | 双方向にVNetリンク、手動登録も考慮 |
| Azure Functions | FlexプランのみVNet統合対応、日本未対応 |
| ネットワークセキュリティ | NSGやルートテーブルの設定に注意 |
| コスト | DNSゾーン・PE・データ転送で増加あり |

---

## 補足：VNet外部からAzure OpenAIを使いたい場合は？

Azure OpenAI は Private Endpoint に対応しているとはいえ、**クライアント側がVNet外にある場合は直接アクセスできない**という制約があります。  
このとき、**Azure Functions を中継プロキシとして使う構成**をとれば、以下のように完全対応可能です。

### 仕組み：
1. 外部からのリクエストは HTTPS で Azure Functions に送る
2. Functions は VNet統合されており、内部から Private Endpoint 経由で Azure OpenAI にリクエスト
3. 応答を外部へ返却

### メリット：
- 外部公開は Functions のみ → **エンドポイントを一元管理できる**
- Azure OpenAI への通信は VNet 内の Private Endpoint 経由 → **セキュアで安定**
- Functions を認証ゲートとして使えば、**認可・監査も可能**

### イメージ構成：

```text
[ 外部クライアント ]
        |
    (HTTPS)
        |
[ Azure Functions (Flexプラン, VNet統合) ]
        |
    (Private Endpoint)
        |
[ Azure OpenAI (海外リージョン) ]

```
## 「VNet外部 ↔ OpenAI」構成は Functions 経由でセキュア＆完全対応！
---

### 結論：Azureでは“できるものは全部プライベートエンドポイントにしておけ”

Azureの世界では「すべてのサービスを同じリージョンにまとめられる」と思うのは幻想です。サービス対応リージョンの制約により、**リージョン跨ぎ構成はむしろ前提**。

その上でセキュアな接続を実現したいなら、**Private Endpoint + DNS構成が唯一の解決策**になります。

---

これからAzureで閉域接続構成を組もうとしてる人が、同じ地雷を踏まないことを祈って！
ドキュメントの翻訳という形のOSS貢献(Zabbix、Pontoon)

[Zabbix](https://www.zabbix.com/jp
)とは、ネットワークやサーバーの監視を自動化するオープンソースの監視ツールです。

こちらの本体およびドキュメントは英語で作成されているのですが、有志による翻訳の場が設けられており、日本語でもZabbixが利用できるようになっております。

私も昨年より翻訳に参加しており、気が付いたら1年経ち、7.0の日本語版ドキュメントの公開にも貢献できたとおもいますので、ちょっと振り返りの記事を残してみたく思います。
(本体(UI)の翻訳もできるのですが、私はドキュメントに注力しているため、ドキュメントについて書いております)

# この記事で一番言いたいこと
Zabbix翻訳者増えてくれ。

## Zabbix翻訳参加について
こちらに翻訳の参加方法、ルールなど記載されております。

https://www.zabbix.com/documentation/guidelines/en/translator_guidelines

こちらが実際に翻訳を投稿するサイトです。

https://translate.zabbix.com/

ざっくりいうと、翻訳投稿サイトに登録するだけで参加できます。
翻訳の投稿単位は大体段落です。
何か申請や審査があるわけではないので、大変気楽に簡単に始められます。

## 翻訳開始した当時、どうだった？
翻訳を開始した[当時](https://qiita.com/Akira_1234/items/619533eade815b4658c5)、Zabbixの最新バージョンは6.4、最新LTSバージョンは6.0でした。
翻訳対象となっていたドキュメントは6.0と6.4のみであり、6.2のドキュメントは英語しかありません。

公開されていた日本語ドキュメントはその実、古くなって内容がそぐわなくなったものまでそのまま公開されたりしておりました。
(↓翻訳が古くなっていたり、翻訳されていない部分があるページにでる表示)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191592/0f1fb896-751b-45fc-800b-2eb2ca3d8620.png)

そもそも翻訳率もちょっと微妙で、さらにLTSでもないからでしょうか、6.4はさらに翻訳率が低く、日本語ドキュメントは鵜呑みにしてはまずいのでは？という疑念が湧くほどでした(6.0: 78%、6.4: 35%)。

## 翻訳して1年、何が起きた？
### Zabbix 7.0(LTS)、7.2のリリース
翻訳対象メンバーに7.0、7.2が追加されました。
これでわかったのですが、翻訳自体はまず直前バージョンのドキュメントを複製しており、原文に変更がなければそのまま正しい翻訳として採用されます(ステータス:Translated)。
原文に変更があったものは翻訳案のような状態で残り(ステータス:Missing)、翻訳されたドキュメントとして公開されます(!?)

翻訳対象メンバーに追加された当時、7.0と7.2の日本語ドキュメントは公開されておりませんでした(公開基準を満たしていなかった)

### Zabbix 6.4が翻訳対象から除外
たしか7.2が追加された少し経った頃、6.4の翻訳ができなくなりました。
日本語のドキュメントの公開が終わったわけではなく、ただ翻訳のみができなくなっております。
先ほど翻訳率が35%だったと書きましたが、50%すら届かない段階だったと思うので、おそらく多くの誤りを含んだままの6.4の日本語訳ドキュメントが公開され続けているということです。

## 翻訳して1年、何ができた？
少しずつですが翻訳を続けてまして、その成果はわかりやすく翻訳率に反映されております。
例えば6.0のドキュメントも72%から87%まで向上し、終わりが見えたというにはもうちょっと遠いですが、確実に進んでおります。

### Zabbix 7.0 日本語ドキュメントの公開
7.0ドキュメントが翻訳に追加された時、翻訳率が42%ほどからスタートしました。
それから51%まで翻訳率が上がり、ついに先日、日本語ドキュメントとして公開されました！
おいかけ翻訳している7.2もドキュメントも49%まで到達しましたので、日本語ドキュメントが公開されるのもそう遠くないと思います。

ちなみに公開の条件の記載は見当たらないのですが、中国語が50%に至る前に公開されていたので全体翻訳率は条件ではなさそうです。
(翻訳が完了したページの割合かなと見当をつけております)

### 褒賞を頂いた
なんとZabbixには翻訳量に伴ったちょっとした褒章が存在し、すべて頂くことができました。
クリアファイルなどのちょっとしたグッズから、リュックサック、最後はなんと[Zabbix認定スペシャリスト](https://www.zabbix.com/jp/training_specialist)を無償でうける権利を頂きました。
自費で受けるとなかなかの値段をしており、まさに現金な話ですがありがたいです。

## 翻訳について
### 正直自信ない
機械翻訳をして変なところを直して公開を続けているのですが、正直なところ内容の正しさに自信がありません。
どうせ英語が読めない人は機械翻訳をするしかないのだから、それよりちょっと上等なものがお出しできれば良いという気持ちでいるのですが、それでもやはり正しさの担保がなさ過ぎて、だれかもっと英語に自信がある人が見なおしてくれないかなあの気持ちです。

### 人手が足りなさすぎる
自分でもなんか謎に頑張ったなと思った1年なのですが、それでも道のりは長く、このペースのままさらに1年経てば6.0の日本語ドキュメントの翻訳率は100%になるでしょうか。
しかしその前に8.0LTSがでて6.0は翻訳対象から外れてしまう気がします。

### そもそもドキュメントの読みやすさとは
英語には自信がないですが、日本語は母国語として生きて久しいので、読みやすい文章についてはかなり考えました。
いわゆる直訳だと読めないわけではないですが、日本語の言い回しとして違和感があり読みづらく、なかなか頭を悩ませる部分となりました。
そしてそもそもドキュメントとして読みやすい文章とは？
このような点でも改善案を出してくれる誰かが欲しく思っています。

## あとがき
なんだかネガティブぎみな文章になってしまいましたが、成果が数値として表示され、また確実に誰かの役に立てているだろうことは大変なモチベーションとなっております。
そして翻訳を通してより細かく集中してドキュメントを読み込むことは自分の学習に大いに役立っているはずです。
まずは翻訳率を、そして次は品質をあげるため、翻訳参加ぜひよろしく願いします！

日本Zabbixユーザー会のイベントがあり、しかも翻訳に関する登壇もありましたので、ここぞとばかりに記事を書きました。
これを機に翻訳者が増えてくれることを願っております……!

翻訳にはだれでも参加できますので、ぜひお願いします。

https://x.com/link_speed/status/1908114139630932439
【TypeScript】error TS6305: Output file '/~/src/App.d.ts' has not been built from source file '/~/src/App.tsx'.

# はじめに
react-testing-libraryの導入で`tsconfig.json`を変更したところ、表題のエラーとなりbuildできなくなりました。エラーの原因と解決方法を備忘録としてまとめました。

# 問題
`tsconfig.json`を下記で設定すると、buildできない。

```json:tsconfig.json
{
  "files": [],
  "references": [
    { "path": "./tsconfig.app.json" },
    { "path": "./tsconfig.node.json" }
  ],
  "compilerOptions": {
    "target": "ESNext",
    "useDefineForClassFields": true,
    "lib": ["DOM", "DOM.Iterable", "ESNext"],
    "allowJs": false,
    "skipLibCheck": true,
    "esModuleInterop": false,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "module": "ESNext",
    "moduleResolution": "Node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx",
    "types": ["node", "jest", "@testing-library/jest-dom"]
  },
  "include": ["src"]
}
```

# 解決方法
`"include": ["src"]`の記述を削除する

このエラーが発生した理由として考えられるのは：
* include": ["src"]を記述することで、コンパイル対象がsrc配下のみとなります
src配下以外も参照している場合、TypeScript はそれらを見つけられずエラーになったと考えられます。

* include設定が競合を起こしていた

```diff_json:tsconfig.json
{
  "files": [],
  "references": [
    { "path": "./tsconfig.app.json" },
    { "path": "./tsconfig.node.json" }
  ],
  "compilerOptions": {
    "target": "ESNext",
    "useDefineForClassFields": true,
    "lib": ["DOM", "DOM.Iterable", "ESNext"],
    "allowJs": false,
    "skipLibCheck": true,
    "esModuleInterop": false,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "module": "ESNext",
    "moduleResolution": "Node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx",
    "types": ["node", "jest", "@testing-library/jest-dom"]
+  }
-  },
-  "include": ["src"]
}
```

# おわりに
設定周り難しいです。

# 参考
https://stackoverflow.com/questions/78091866/typescript-build-error-ts6305-type-declaration-file-output-file-has-not-been-bu