OmniAICreator/Qiita-1.07M huggingface dataset:
バッファ付きチャネル【Go】

## はじめに

Goにおいてバッファ付きチャネルの基本と利点を整理する。

### バッファ付きチャネルの基本

バッファサイズは、チャネル内に一時的に保持できる値の最大数。

以下の場合、c は最大10個の整数を保持できる。

```Go
c := make(chan int, 10)
```

送信側（```c <- x```）は、チャネルのバッファに空きがあれば即座にデータを送信できる。

受信側（```<-c```）は、チャネルのバッファにデータがあれば即座にデータを受け取れる。

### バッファ付きチャネルの利点

バッファ付きチャネルを使用することで、送信側と受信側の処理を完全に同期させる必要がなくなり、非同期的に動作できるようになる。

#### 非バッファ付きチャネルの場合

・非バッファ付きチャネルでは、送信側と受信側は必ず同時に通信しなければならない。
・送信側が値を送信しようとすると、受信側がその値を受け取るまでブロックされる（待機する）。
・同様に、受信側が値を受け取ろうとすると、送信側が値を送信するまでブロックされる。

#### バッファ付きチャネルの場合

・バッファ付きチャネルでは、バッファに空きがある限り、送信側は値を送信してすぐに次の処理に進むことができる（非同期的に動作できる）。
・バッファにデータがある限り、受信側も即座に値を受け取ることができる。
・バッファがいっぱいになると、送信側は再びブロックされる（受信側がデータを消費するまで待機）。
・バッファが空の場合、受信側は再びブロックされる（送信側がデータを送るまで待機）。

### 具体例での違い

#### 非バッファ付きチャネルの場合

送信側（```c <- 1```）は受信側（```<-c```）が準備されるまでブロックされる。
結果として、送信側と受信側は必ず同時に動作しなければならない。

```Go
c := make(chan int)

go func() {
    c <- 1 // 受信側が準備されるまでブロックされる
    fmt.Println("送信完了")
}()

fmt.Println(<-c) // 値を受信してブロック解除
```

#### バッファ付きチャネルの場合

送信側は2つの値をバッファに送信して、次の処理に進むことができる。
受信側もバッファから値を取り出すため、両者が同期していなくても問題ない。

```Go
c := make(chan int, 2)

go func() {
    c <- 1 // バッファに空きがあるので即座に送信可能
    c <- 2 // 2つ目も即座に送信可能
    fmt.Println("送信完了")
}()

fmt.Println(<-c) // バッファから即座に受信可能
fmt.Println(<-c) // 2つ目も即座に受信可能
```

### A Tour of Goでの実例

```fibonacci``` 関数（ゴルーチン）と ```main``` 関数は柔軟に非同期で動作することができる。

```Go
package main

import (
	"fmt"
)

func fibonacci(n int, c chan int) {
	x, y := 0, 1
	for i := 0; i < n; i++ {
		c <- x
		x, y = y, x+y
	}
	close(c) // チャネルを閉じると、受信側が送信終了を検出できる
}

func main() {
	c := make(chan int, 10) // チャネル c に最大10個の値をバッファリング
	go fibonacci(cap(c), c)
	for i := range c {
		fmt.Println(i)
	}
}
```

**fibonacci 関数の送信部分**

```go
c <- x
```
この送信操作は、バッファがいっぱいでない限りブロックされない。
バッファがいっぱいになると、受信側（```for i := range c```）がデータを消費するまで待機する。

**main 関数の受信部分**
```Go
for i := range c {
    fmt.Println(i)
}
```
チャネルに値があればすぐに受信して出力する。
チャネルが空の場合、送信側がデータを送るまで待機する。
【ゼロからのOS自作入門】Day05

Day05を読み終えました。

フォントは、このように作られている（表示されている？）のか。
フォントの作り方は、興味はなかったけど、勉強になった。
0x21 '!'
........
...@@...
...@@...
...@@...
...@@...
...@....
...@....
...@....
...@....
...@....
...@....
........
........
...@....
...@....
........
(その2).構造体で遊ぶ。(中身を見る)


x M5NanoC6での予定は、未定

目的
強制キャストして中身を見て遊ぶ

いろいろ
むずかしい、書き方をすると
渋谷の交差点にいる「ネコと和解せよ」?の人?になるので
簡素な書き方をする?(なに言ってんだかわからない!!!)
(ここは、東京近郊です。(毎日、渋谷は、花火大会か、お祭りの様に混んでいる(あたりまえ)))


オンラインコンパイラ

```c++

#include <iostream>
using namespace std;
int main(void){
    // Your code here!
    printf("START\n");
    
    struct {
        char a = 'A';
        char b = 'B';
        char c = 'C';
    } ABC;
    
    char *c;
    c = (char *)(&ABC);

    printf("a=[%c]\n",c[0]);
    printf("b=[%c]\n",c[1]);
    printf("c=[%c]\n",c[2]);
    
}//main



```


```

START
a=[A]
b=[B]
c=[C]


```
PayPay API Springbootで配置  爆速

https://developer.paypay.ne.jp/

# 1.Mavenで配置
```Java
<dependency>
    <groupId>jp.ne.paypay</groupId>
    <artifactId>paypayopa</artifactId>
    <version>1.0.8</version>
</dependency>
```

# 2.ユーザー認証
```java
private static final String YOUR_API_KEY = "";
private static final String YOUR_API_SECRET = "";
private static final String YOUR_MERCHANT_KEY = "";
private static final ApiClient apiClient;
static {
    try {
        apiClient = new Configuration().getDefaultApiClient();
        apiClient.setProductionMode(false);
        apiClient.setApiKey(YOUR_API_KEY);
        apiClient.setApiSecretKey(YOUR_API_SECRET);
        apiClient.setAssumeMerchant(YOUR_MERCHANT_KEY);
    } catch (ApiException e) {
        throw new RuntimeException(e);
    }
}
```

# 3.1 CreateQRCode
```java
	/**
     * CreateQRCode
     *
     * @param merchantPaymentId 
     * @param payAmount 
     * @param orderDescription 
     * @return 
     */
    public static QRCodeResponse getQrCode(String merchantPaymentId, Integer payAmount, String orderDescription) throws ApiException {
        QRCode qrCode = new QRCode();
        qrCode.setAmount(new MoneyAmount().amount(payAmount).currency(MoneyAmount.CurrencyEnum.JPY));
        qrCode.setMerchantPaymentId(merchantPaymentId);
        qrCode.setCodeType("ORDER_QR");
        qrCode.setOrderDescription(orderDescription);
        qrCode.isAuthorization(false);
        PaymentApi apiInstance = new PaymentApi(apiClient);
        QRCodeDetails response = apiInstance.createQRCode(qrCode);
        QRCodeResponse responseData = null;
        if (PAY_SUCCESS.equals(response.getResultInfo().getCode())) {
            responseData = response.getData();
        } else {
            log.info("バーコード生成，Error code : {}", response.getResultInfo().getCode());
            throw new RuntimeException((response.getResultInfo().getMessage()));
        }
        return responseData;
    }
```

## 3.1.1 Test result
```java
private static final String PRODUCT_PAY_PAY = "PayOr";

@Test
public void createPaymentTest() {
    String orderNo = IdUtil.getSnowflake(0, 0).nextIdStr();
    System.out.println("注文番号をランダムに生成する" + orderNo);
    QRCodeResponse QRCodeResponse = new QRCodeResponse();
    try {
        String merchantPaymentId = PRODUCT_PAY_PAY + orderNo;
        String orderDescription = "テスト";
        Integer paAmount = 1;
        QRCodeResponse = getQrCode(merchantPaymentId, paAmount, orderDescription);
    } catch (ApiException e) {
        System.out.println("Error code : " + e.getMessage());
        throw new RuntimeException(e);
    }
    System.out.println(QRCodeResponse);
    System.out.println(QRCodeResponse.getUrl());
}
```
僕が小学生中学生c時代プログラミングを勉強していた話

## 小学生でプログラミングを勉強していた話
ハロー中学生エンジニアです、小学生でプログラミングの話をする前にお前はなんの技術ができるんだ言って話をしたいと思います.
 * Nextjs
 * Vue
 * Rails
 まあまあこんな感じです、なんで話したかったというと自慢したかっただけです、自分で言うのもあれだけど、中学生でここまでできるのは自分でもすごいと思います、勉強はできないけど、、、学校でもこんな話をできる人もおらず悲しかったです、

 ### 小学生中学生でプログラミングを勉強していた話をしたいと思います

まず何年生で始めたの3年生です今は中学人ねせいなのでプログラミング歴で言ったら5年目ですね、五年間もやったからNextjsやVueができるってわけではありません、小学3年生から小学6年生まで、プログラミングをやっていたかって言ったら、ほぼやってないですねそもそも勉強方が間違っていました、私が思うプログラミング勉強法といえばとりあえずわかんなくてもススメだとおも持っているんですよ、ですけど3から6年の頃は完璧主義すぎて今やってることを完全に理解しなくちゃいけないこ言うことですね、その頃は周りから教えてもらえることもできずにずっと1人でyoutubeと睨めっこそんまま中学に上がりよくわかんないですけどがけ学年委員長になっていました、なっていましたと言うと、責任転嫁んみたいになっちゃうので自分から手をあげました、ですけど夏に事件後起きました学校に行かなくなる、そんなことがあり、時間は有り余るほどできてしまいました、もうその頃にはプログラミングの熱は冷めていて、ですけどこのままだと何にもできることはなく学校にも行かずただのニートになってしまうと思いもう一回プログラミングの勉強法を調べ毎日12時間以上プログラミングをやっていきなんか中学2年生になっていました、中学2年生になり新学期とう言うことで頑張って最近は学校に行っています、結論何が言いたいかって言うとわかんないです。
読んでいただきありがとうございます、エンジニアの会社員の人がいれば中学卒業したらコネで入社させてくだいさいべん今日はできないけど技術はありますgit載せときます私が一番頑張って作ったやつですバックエンドの技術はありませんけどまあお願いね

https://github.com/boyintyoko/clock-web
Viteのプロジェクトにtailwindcss入れたけど動かないときにやったこと

`tauri`でフロントエンドをvite+ts+reactにしてtailwindcss入れてみたけどなんか動かんな？ってなったときの備忘録
結論から言うと`tailwind`と`autoprefixer`を`vite.config.ts`の`plugins`に記載すると動きました

[公式サイト](https://tailwindcss.com/docs/guides/vite)では以下の設定すれば使えるよ！とありました
1. `npm install -D tailwindcss postcss autoprefixer` `npx tailwindcss init -p`
1. `tailwind.config.js`に`content`を追加して、必要なファイル(htmlやts,tsx)を追加する
1. `index.css`つくって`@tailwind`の命令を書いて`App.tsx`などからimport
1. コードからtailwindのクラスを呼ぶ

ところが上記だけでは動かなかったので、`vite.config.ts`に以下追加すると動きました
```diff_typescript
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
+import tailwind from "tailwindcss";
+import autoprefixer from "autoprefixer";

export default defineConfig(async () => ({
  plugins: [react()],
+ css: {
+   postcss: {
+     plugins: [tailwind, autoprefixer]
+   }
+ },

  // Vite options tailored for Tauri development and only applied in `tauri dev` or `tauri build`
  //
  // 1. prevent vite from obscuring rust errors
  clearScreen: false,
  // 2. tauri expects a fixed port, fail if that port is not available
  server: {
    port: 1420,
    strictPort: true,
    host: host || false,
    hmr: host
      ? {
          protocol: "ws",
          host,
          port: 1421
        }
      : undefined,
    watch: {
      // 3. tell vite to ignore watching `src-tauri`
      ignored: ["**/src-tauri/**"]
    }
  }
}));

```
【ネットワーク】TCP/IP インターネット層

# はじめに
こんにちは。アメリカで独学でエンジニアを目指している者です。
現在ネットワークについて学んでいるのですが、その中でも本日はTCP/IPのインターネット層について見ていきたいと思います

## インターネット層の役割
インターネット層の主な役割は、エンドツーエンドのパケット転送（ルーティング） です。ネットワーク間でデータを転送する際に、送信元から宛先までパケットを届けるための経路選択（ルーティング）と、宛先を特定するためのアドレス指定を担っています。

  * ルーティング (Routing)
  ルータやL3スイッチなどのネットワーク機器が、IPパケットを最適なルートで宛先に届けるために利用する仕組みです。

  * アドレッシング (Addressing)
  デバイス（ホスト）を一意に識別するためにIPアドレスを割り当て、経路決定で利用します。IPv4アドレス、IPv6アドレスなどが使われます。

## ンターネット層の主要プロトコル
### IP (Internet Protocol)
インターネット層の中心となるプロトコルが IP です。IPは、データをパケット（IPパケット）と呼ばれる単位で分割し、宛先と送信元のIPアドレスをもとにパケットを転送します。主に以下のバージョンがあります。

  1. IPv4 (IP version 4)
  32ビット(約43億通り)のアドレス空間を持ちます。例: 192.168.0.1

  2. IPv6 (IP version 6)
  128ビットのアドレス空間を持ち、膨大な数のデバイスを識別できるようになっています。
  例: 2001:0db8:85a3:0000:0000:8a2e:0370:7334

IPパケットには、以下の情報が含まれます。

  * 送信元IPアドレス
  * 宛先IPアドレス
  * データ（ペイロード）
  * TTL (Time To Live) などの制御情報

### ICMP (Internet Control Message Protocol)
ICMP は、IPによる通信を補助するプロトコルです。指定した相手にパケットが到達可能かどうかを検査し、到達できない場合はその理由を通知するなど、トラブルシューティングや状態確認に用いられます。

# まとめ
TCP/IPモデルのインターネット層では、IPアドレスを用いたルーティングによってデータを届ける仕組みが整備されています。次回はトランスポート層について記事を書きたいと思います。
非同期タスクの並列処理をパフォーマンス計測してみた

こんにちは！TypeScriptやPythonの言語をメインに扱っているエンジニアのさわらと申します。

今回は、非同期タスクを並列処理することで、パフォーマンスに、どの程度、影響するのかが気になったので計測してみました。

複数の非同期APIリクエストを処理する想定でいきます。

利用させていただくのはみんな大好きJSONPlaceholderです。

無料プランだと大量のデータは扱えないと書かれてはいるのですが、具体的な記述がないので、今回は、とりあえず50件ほどフェッチしてパフォーマンスを計測してみたいと思います。

以下、公式サイトです。
https://my-json-server.typicode.com/

また言語はTypeScriptで実行環境は、TypeScript Playground（ブラウザ上の実行環境）となります。

<details><summary>実装を確認する</summary>

```TypeScript
const fetchPost = async (id: number): Promise<any> => {
  const response = await fetch(`https://jsonplaceholder.typicode.com/posts/${id}`);
  if (!response.ok) {
    throw new Error(`Failed to fetch post with ID ${id}`);
  }
  const data = await response.json();
  console.log(`Fetched post for ID ${id}`);
  return data;
};

const sequentialFetch = async (ids: number[]): Promise<any[]> => {
  const results: any[] = [];
  console.time("Sequential Fetch"); // 時間計測開始
  for (const id of ids) {
    const result = await fetchPost(id); // 逐次処理
    results.push(result);
  }
  console.timeEnd("Sequential Fetch"); // 時間計測終了
  return results;
};

const parallelFetch = async (ids: number[], maxParallel: number): Promise<any[]> => {
  const results: any[] = [];
  console.time("Parallel Fetch"); // 時間計測開始

  for (let i = 0; i < ids.length; i += maxParallel) {
    const group = ids.slice(i, i + maxParallel);
    const groupResults = await Promise.all(group.map((id) => fetchPost(id))); // 並列処理
    results.push(...groupResults);
  }

  console.timeEnd("Parallel Fetch"); // 時間計測終了
  return results;
};

// メイン実行
(async () => {
  const ids = Array.from({ length: 50 }, (_, i) => i + 1);
  const maxParallel = 5; // 最大並列数

  console.log("\n=== Sequential Processing ===");
  await sequentialFetch(ids);

  console.log("\n=== Parallel Processing ===");
  await parallelFetch(ids, maxParallel);
})();


```
</details>

# パフォーマンスを計測してみる

## 順次処理
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3490265/cee4d05a-a1b9-6ce8-ce95-9e3368280958.png)
結果:20323.194091796875 ms

## 並列処理
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3490265/4b3881fe-5258-d7c6-e8ae-f0fe2219467a.png)
結果:525.485107421875 ms

# 結果
測定した結果、並列処理の方が約38.7分の1ほど処理時間が短縮できました。思ったより劇的に変わるという印象です。

並列処理では処理の順序が保証されない点に注意が必要なので、タスクの依存関係が強い場合は、工夫が必要そうですが、検討の価値は十分にあると感じました。

他にも、こんなパフォーマンス改善の手法があるよ！などありましたら気軽にコメントで教えていただけると嬉しいです！
個人的な備忘録：クラスと関数の違いを理解するために、簡単なコード例を使ってアウトプットしてみた

## はじめに

最近、Pythonを使ったプログラムを書いていなかったため、自分自身の理解を深めることや復習を目的として、今回はクラスと関数の違いについてまとめていきます。

:::note info
本記事の内容は個人の備忘録レベルとなっております。***その点をご理解いただければ幸いです。***
:::

具体的なコード例を見ながら、クラスと関数の違いについて自分なりに整理していきます。

## 書こうと思ったきっかけ
普段、AWSのLambda関数を使う際によくPythonを活用していますが、最近はLambdaを使う機会が減っていました。

:::note warn
***そのため、改めてクラスと関数の違いについてまとめてみようと思いました。***
:::

それぞれの違いを体系的に整理することで、後から振り返った際に、自分の知識としてこの記事を活用できると考えています。

**しっかりとアウトプットしていきたいと思います。**

## クラスと関数について
ここでは、クラスと関数について簡単にまとめていきます。***この内容が、どなたかの学習の参考になれば幸いです。***

### 関数の概要

- **定義**: 特定の動作や計算を実行するためのコードのまとまり。
- **使い方**: 入力（引数）を受け取り、出力（戻り値）を返す。
- **目的**: 一般的な処理を簡潔にまとめて再利用しやすくする。

**例:**

```py
def greet(name):
    return f"Hello, {name}!"

# 関数の呼び出し
print(greet("Alice"))  # 出力: Hello, Alice!
```

この場合、`greet` は名前を受け取って挨拶のメッセージを生成する関数です。

### クラスの概要

- **定義**: データ（属性）とそのデータを操作するための機能（メソッド）をまとめた設計図。
- **使い方**: クラスからオブジェクト（実体）を生成して使う。
- **目的**: 関連するデータと機能をひとまとめにして、再利用性や拡張性を高める。

**例:**

```py
class Greeter:
    def __init__(self, name):
        self.name = name

    def greet(self):
        return f"Hello, {self.name}!"

# クラスを使ってオブジェクトを生成
greeter = Greeter("Alice")
print(greeter.greet())  # 出力: Hello, Alice!
```

この場合、`Greeter` クラスは名前を保持し、挨拶を生成するための設計図です。

**`Greeter` を使って作られた `greeter` オブジェクトが greet メソッドを使って挨拶を生成します。**

### 違い（簡単に）

- **関数**: 単一の処理を実行するためのツール。
- **クラス**: データとその操作をまとめて管理するための仕組み。

## 主な違い

- **データの保持**:
  - 関数: 一時的なデータ処理に使われることが多い。
  - クラス: データ（属性）を長期間保持し、それを操作するための方法（メソッド）を定義する。

- **再利用性**:
  - 関数: 単一のタスクを処理するのに適している。
  - クラス: 複雑なデータと機能をまとめて再利用するのに適している。

:::note warn
**この違いを覚えておくと、使い分けが簡単になります！**
:::

## まとめ
ここまでお読みいただき、ありがとうございました。***今回は、基本的なクラスと関数の違いについてまとめてみましたが、自分自身にとっても非常に勉強になる機会となりました。***

:::note info
**これからも分からないことに積極的に向き合い、アウトプットを通じて理解をさらに深めていきたいと思います。**
:::

この記事が少しでも皆さんのお役に立てれば幸いです。
AzureBlobStorageへのファイルアップロードで詰まった


# 概要
PowerShellを使用して、Azure Virtual MachinesからAzure Blob Storageへのファイルアップロードする機能の実装で詰まったので、その解決策を共有します。


# 詰まったこと

まずは以下のドキュメントを参考にして、ファイルをアップロードしようとした。
```
Set-AzStorageBlobContent -Container $containerName -File $zipPath -Blob $blobName -Context (Get-AzStorageAccount -ResourceGroupName $resourceGroupName -Name $storageAccountName).Context
```
https://learn.microsoft.com/ja-jp/azure/storage/blobs/storage-quickstart-blobs-powershell

## エラー発生
ただ、以下のようなエラーが出てしまった。
```
Get-AzStorageAccount : No subscription found in the context.  
Please ensure that the credentials you provided are authorized to access an Azure subscription, 
then run Connect-AzAccount to login.
```

## エラーの原因
このエラーの原因は、PowerShellセッションでAzureサブスクリプションにログインしていないか、ログイン情報が有効ではないためである。今回はログイン処理をPowershellで実装するなどは行なっていないためこのようなエラーが起きた。Get-AzStorageAccountコマンドは、Azureのサブスクリプションに接続されている必要があるが、環境が他社によって管理されており、ファイルをAzure Blob Storageにアップロードするだけなので連携コストやログインするための設定を追加する工数を考慮すると、他に解決策がないかを検討した。

# 解決策
以下の記事を参考にして、AZCopyを使用してファイルをアップロードすることで簡単に解決できた。ありがとうございます！

https://qiita.com/yuta1123/items/702eb7cab8479344fbc8

## なぜAZCopyで解決できたのか
PowerShellのコマンドは、Azureサブスクリプションの認証情報が必要だが、AZCopyでは、SASトークンやストレージアカウントのキーを使って直接認証を行うことができるため、Azureサブスクリプションに対するログインが不要で簡単に解決できた。これにより、適切なSASトークンやアクセスキーがあれば、スムーズにファイルのアップロードが可能になった。


# 参考

https://learn.microsoft.com/ja-jp/azure/storage/blobs/storage-quickstart-blobs-powershell

https://qiita.com/yuta1123/items/702eb7cab8479344fbc8
＜個人的な備忘録～フロントエンド編～＞HTMLの書き方①

## はじめに
ハッカソンでフロントエンドを担当する機会を頂きましたが、理解が乏しいため備忘録として記事に残し、少しでも整理していきたいと思います。
個人的な備忘録です。IT未経験のため間違っている点がありましたらご指摘いただけますと幸いです。

## HTMLの書き方について
チームメンバーに相談したところ、HTMLの書き方は人によって違いがあるとのことでした。
調べてみたところ、書き方のスタイルにはセマンティックな書き方とdiv要素を使う書き方の大きく二つあるようです。いろいろなコードを見ていて、「なんで同じような内容なのに書き方が違うんだ？」という疑問が解消されました。

## セマンティックな書き方
要素の名前が明示的な意味を表しているHTMLの書き方です。具体的には、`<div>`を使わず、`<header>`や`<main>`などの役割の定まっているタグを使用します。ブラウザ上では`<div>`を使って記載した場合と見え方は同じなので、あくまで明示的な表現をしているだけということになります。

以下の記事が参考になりました。
- セマンティックなタグの基本や利点について
https://webst8.com/code/html-semantics/
- HTMLタグの詳細な説明について
https://developer.mozilla.org/ja/docs/Web/HTML/Element

## メリット
1. 可読性が向上する
役割の決まったタグを使用するため、他の人が読んだ時に内容を理解しやすくなります。
2. 保守性が向上する
長期的にみて、他の開発者がコードを理解しやすく、修正が容易になります。
3. SEOに有利
検索エンジンはセマンティックなHTMLを利用してページ構造を理解するため、適切にタグを使うことで検索順位が向上する可能性があります。

## 注意点
1. 学習コストが少し高い
相対的にというレベルだと思いますが、各タグの正しい使い方を調べるための時間的コストがかかります。


## divを多用する書き方
タグ自体は、例えば`<main>`を使っても`<div>`を使ってもブラウザ上での見え方は変わらないため、`<div>`を多用してページを構築することもできます。

## メリット
1. シンプルで書きやすい
2. 速く書ける

## 注意点
1. 可読性が低下する
`<div>`の入れ子構造が深くなってくると理解しにくくなります。
2. 保守性が低下する

## まとめ
初学者としては、まずはセマンティックな書き方に挑戦してみようと思いました。ですが、`<div>`を使った書き方についてもコードをみて理解できるように学習していきたいと思います。
シンタックスハイライターを作りたい!!

### javascriptでシンタックスハイライターを作りたい
まずはこれを見てください↓
```javascript:sample.js 
function helloworld(){
  console.log("hello world");
}
```
これはシンタックスハイライトと言って、コードを読みやすくするために
特定の文字を色付けする技術です。
今回はこれを自作してみようと思います。

## 1.ファイルの用意

早速作っていこうと思いますがまずファイルを用意しようと思います
### 今回必要なファイル

1.code.html 　    シンタックスハイライトしてほしいコードを書きます
2.script.js　ハイライト処理をしていきます

今回はこれだけです。

## それぞれのコードは
```html:code.html 
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>コード</title>
     
</head>
<body>
<script src ="script.js"></script>
  <pre><code>function helloworld(){
    console.log("hello world");
}</code></pre>
</body>
</html>
```
コード部分は適当です
```javascript:script.js 
document.addEventListener('DOMContentLoaded', (event) => {
var code = document.getElementsByTagName("code");

});
```
これで準備は出来ました
次は次回で
Uncaught AbortError: 音声再生エラーを解決する試み

## はじめに
音声ファイルを動的に変更する必要があるアプリケーションを作成中に、以下のようなエラーに直面しました

`"Uncaught (in promise) AbortError: The play() request was interrupted by a new load request."`

自分がどのように解決したかを共有します。

## 問題の状況
**実現したかったこと**
- React を使って音声を動的に切り替える
- src を変更したら自動で再生する


## 初めのコード
```react:qiita.rb
const AudioComponent = ({ src }: { src: string }) => {
  const audioRef = useRef<HTMLAudioElement>(null);

  useEffect(() => {
    if (audioRef.current) {
      audioRef.current.src = src;
      audioRef.current.play(); 
    }
  }, [src]);

  return <audio ref={audioRef}></audio>;
};
  ```
  これではエラーが出てしまいました

## エラーの原因

**1\.** `audioRef.current.src = src `によって音声ファイルの URL が設定されると、ブラウザは自動的に音声リソースのロードを開始します。

このとき、以下のようなイベントが順番に発生します（一例）。
- `loadstart`
- `progress`
- `loadedmetadata`
- `loadeddata`
- `canplay`
- `canplaythrough`


**2\.**  同時に `audioRef.current.play()` を呼び出すと、まだ十分なデータを読み込めていない段階で再生要求が走るため、ブラウザが再生リクエストを中断 (abort) し、`AbortError` が発生する場合があります。



## 解決方法

`onLoadedData` イベントを利用して、リソースのロードが完了した後に再生を開始するように変更します。

`onloadeddata` イベントが発生したタイミングでは、少なくとも 最初のフレームを再生できるだけのデータ が読み込まれています。そのため、このイベントより後に再生を開始すれば、AbortError の発生を防ぐことができます。



**修正版コード**
```react:qiita.rb
const AudioComponent = ({ src }: { src: string }) => {
  const audioRef = useRef<HTMLAudioElement>(null);

  useEffect(() => {
    if (audioRef.current) {
      audioRef.current.src = src;
    }
  }, [src]);

  const handleLoadedData = () => {
    if (audioRef.current) {
      audioRef.current.play();
    }
  };

  return <audio ref={audioRef} onLoadedData={handleLoadedData}></audio>;
};
  ```

  ## 結果
上記のコードに変更することで、`AbortError` が発生せず、音声のソースを切り替えるたびに自動的に再生が始まるようになりました。


## まとめ
音声や動画の動的な切り替えを扱う際には、`onLoadedData` を活用して、リソースのロード完了後に再生を開始する方法が有効です。

もし誤りや補足があれば、ご指摘いただけると助かります。

## 参考

https://developer.mozilla.org/ja/docs/Web/HTML/Element/audio

https://developer.chrome.com/blog/play-request-was-interrupted?hl=ja
AWS Cloud Practitionerの合格体験談

# はじめに

今回は2024年10月にAWS Cloud Practitionerの試験に合格したので、その体験談についてお話ししようと思います。この試験を受けた背景や、実際に行った勉強方法、そして感じたことを共有します。これから挑戦する方の参考になれば幸いです。

# 資格試験を受けた経緯

もともと私はオンプレミス環境でプログラムを開発する業務に従事していました。しかし、一念発起して受託開発系の企業に転職しました。その企業では主にクラウドを利用したWebサイトの開発を手掛けており、私はそこで初めてAWSに触れました。実際にAWSに触れてみると、自分の知識があまりにも乏しいと感じ、まずは基礎から学び直そうと考えました。その第一歩としてAWSの資格取得を目指すことに決めました。

勉強方法

勉強は主にアウトプットを重視し、1か月間Udemyの講座を取り組み続けました。(下記のリンクが私が取り組んだ講座です！！)

[【CLF-C02版】この問題だけで合格可能！AWS 認定クラウドプラクティショナー 模擬試験問題集（6回分390問）](https://www.udemy.com/share/101SaA3@exglhhATRh603_6reQVo7JJU1JQ63k2aOLnkzlspqAaTVmf2HWOlpXuUZpeqJ4Z0rw==/)

最初の土日を使って講座全体の問題を一通り行って、自分の理解度を確認しました。毎日1時間程度の時間を確保して、復習と演習を繰り返しました。間違えた問題や理解が不十分な箇所は、関連するAWSドキュメントや追加の教材を参照して知識を深めました。3週間目くらいになってくるとさすがにサービスについての理解が深まってきていたので、平日は30分くらいまで学習時間を短縮できるようになっていたので、ほかの気になっている分野の勉強も交えつつ行っていました。

# 感想

AWS Cloud Practitionerの試験は、各問題に対して適切なAWSサービスを選ぶ能力が問われるので、演習時間をしっかりと確保して、問題形式に慣れることが合格の鍵だと感じました。

ただし、この試験の受験費用は税込みで16,500円と高額です。そのため、効率よく勉強時間を確保して挑むことが重要だと思います。

また、社会人になると勉強時間を確保するのが難しいことを実感しました。私は平日の隙間時間や通勤時間を活用しつつ、計画的に学習を進めました。しんどいと感じる部分もありましたが、昇給にも影響してくる重要な資格試験だったので、何とかやりきることができました。

# 最後に

AWS Cloud Practitionerは、クラウドの基礎知識を身に付けたい方にとって非常に良い試験だと思います。これから受験する方は、自分に合った学習方法を見つけ、ぜひ挑戦してみてください！
VLANとは

### スイッチの特徴
>ネットワーク上に配置される通信機器は、自分が処理するレイヤ（階層）以下のレイヤプロトコルを解釈できる特徴があります。レイヤ３スイッチは（以下、L3SWという）は、L2レベルのスイッチングにも対応しています。

自分宛ではなかったらレイヤ２で捨てる
### VLANの構築
>スイッチの特徴的な機能にVLAN(Virtual LAN:仮想LAN)機能があります。VLANとは、物理的な接続形態に依存せず、`ノードを任意に論理的なグループに分ける`ための仕組みのことで、L2機能とL3機能の接続性を拡張したのがVLAN機能です。

同じ物理的な接続をされていてもVLANによって論理的に分けることができる

### VLANの特徴
ブロードキャストドメインの分割、各VLANは、ルータやL3SWで分割されたネットワークと同じように機能するので、「VLAN＝ブロードキャスト＝サブネット(論理ネットワーク）と定義できる。

ブロードキャストの範囲を決める
### VLAN ID
>VLAN機能を持っているL3SWは、ポート番号の先に存在するノードにVLAN　IDを設定する

VLAN IDでグループを作ることによってIPアドレスが異なっていてもネットワークの分割・統合を行うことができる。ネットワークの運用に柔軟性を持たせることができる。

### ポートVLAN
>スイッチのポートごとにVLANを割り当てる方式です。スタティックVLANとも呼ばれ、この方式では、ポートとVLANの対応が固定されます。

ポートに接続した時点でVLANが決まる

### タグVLAN
>VLAN IDを含むタグ情報をMACフレームに埋め込み、フレーム単位で、VLANを区別する方式です。VLANが論理的に構成されるため、一つのポートが複数のVLANに参加したり、結線を変えずに参加するVLANを変更したりすることが可能です。

MACフレームにVLANをつけることができる。物理層、データリンク層でもVLANを知らせることができる。

### 遠隔地LANの結合
>VLAN IDは、IPアドレスに対して透過的なので問題ありません。このようにして遠隔地のネットワークを同じLANグループとして管理することもできます。

離れていてもVLAN IDが同じであれば同じLANにすることができる。

https://gihyo.jp/book/2023/978-4-297-13865-3
LLaMA-Factoryでgoogle/gemma-2-2b-jpn-itのファインチューニングをサポートする方法


## はじめに
LLaMA-Factoryは、さまざまな言語モデルを簡単にファインチューニングできる便利なツールです。今回は、LLaMA-Factoryで`google/gemma-2-2b-jpn-it`モデルのファインチューニングをサポートするための手順を紹介します。

## 手順

### 1. `constants.py`の編集
まず、`constants.py`ファイルを編集して、`google/gemma-2-2b-jpn-it`モデルを追加します。

```bash
vi ./src/llamafactory/extras/constants.py
```

以下のように、`Gemma-2-2B-JPN-Instruct`のエントリを追加します。

```python
        "Gemma-2-2B-Instruct": {
            DownloadSource.DEFAULT: "google/gemma-2-2b-it",
            DownloadSource.MODELSCOPE: "LLM-Research/gemma-2-2b-it",
            DownloadSource.OPENMIND: "LlamaFactory/gemma-2-2b-it",
        },
        "Gemma-2-2B-JPN-Instruct": {
            DownloadSource.DEFAULT: "google/gemma-2-2b-jpn-it",
        },
        "Gemma-2-9B-Instruct": {
            DownloadSource.DEFAULT: "google/gemma-2-9b-it",
            DownloadSource.MODELSCOPE: "LLM-Research/gemma-2-9b-it",
            DownloadSource.OPENMIND: "LlamaFactory/gemma-2-9b-it",
        },
```

### 2. 変更の適用
編集が終わったら、ファイルを保存して変更を適用します。

## まとめ
これで、LLaMA-Factoryで`google/gemma-2-2b-jpn-it`モデルのファインチューニングが可能になりました。この変更により、日本語の指示に特化したモデルのファインチューニングがより簡単に行えるようになります。

## 参考
- [LLaMA-Factory GitHubリポジトリ](https://github.com/hiyouga/LLaMA-Factory)
- [Google Gemmaモデル](https://huggingface.co/google/gemma-2-2b-jpn-it)

この記事が役に立ったら、ぜひいいねやシェアをお願いします！
Python シャローコピーとディープコピーの違い

Pythonでは、オブジェクトをコピーする際に「シャローコピー」と「ディープコピー」という2つの方法がある。

## シャローコピー
- コピーしたオブジェクトと元のオブジェクトは同じメモリを参照する
- コピーしたオブジェクトの浅い層を更新しても、元のオブジェクトは変更されない
- コピーしたオブジェクトの深い層を更新すると、元のオブジェクトが変更される
- メモリ効率は良いのでパフォーマンスはいい

```python
import copy

original = {"a": {"nested": 1}, "b": 2}
shallow_copy = copy.copy(original)

# シャローコピー後の変更
shallow_copy["a"]["nested"] = 99
shallow_copy["b"] = 999

print("Original:", original)  # {'a': {'nested': 99}, 'b': 2}
print("Shallow Copy:", shallow_copy)  # {'a': {'nested': 99}, 'b': 999}

```

## ディープコピー
- 元のオブジェクトと、コピーしたオブジェクトは独立している

```python
import copy

original = {"a": {"nested": 1}, "b": 2}
deep_copy = copy.deepcopy(original)

# ディープコピー後の変更
deep_copy["a"]["nested"] = 99

print("Original:", original)  # {'a': {'nested': 1}, 'b': 2}
print("Deep Copy:", deep_copy)  # {'a': {'nested': 99}, 'b': 2}

```

## まとめ

| **特徴**   | **シャローコピー**        | **ディープコピー**          |
| -------- | ------------------ | -------------------- |
| ネスト部分の参照 | 共有する               | 独立する                 |
| 影響範囲     | ネストされた部分を変更すると影響する | 完全に独立しているため影響しない     |
| 処理の深さ    | 表層的なコピー            | 再帰的に全てをコピー           |
| パフォーマンス  | 高速 (ネストが少ない場合)     | 遅い (ネストが深い場合は時間がかかる) |
Java Silver SE11合格体験談

去年4月にOracleのJava Silver SE11を受験し、合格することができたので勉強方法や試験概要について共有いていこうと思います。

受験時期：2024/4月上旬
得点率：93%

### 当時のスペック
・社会人2年目になりたて
・研修で半年ほどJavaやSQL,HTML&CSSなどの最低限の知識を学んだ
・現場ではJavaを使う部署にはいないので、Javaの実務経験はない

自分は研修時代、本当にJavaが苦手だったのでついていけてませんでした。
半年の研修を経て、何かITに関する武器が欲しいと思い、Javaの学習を本格的に始めました。
1つの目標、基準としてJava Silverを取得するということを決めたのが受験のきっかけです。



### 必須アイテム
・徹底攻略Java Silver SE11問題集
いわゆる黒本というやつです。
これだけで十分です。
これをやり込めば、試験は必ず合格！と言っても過言ではないくらい詳しく丁寧な説明が書かれてます。
実際の試験もこの黒本の類題がかなりの割合で出題されています。
(※2025/1/19現在時点で、Java Silver SE17という最新の黒本がでてました。)


### 勉強方法
研修で学んだとはいうものの、ほとんど理解していなかったので黒本を最初から丁寧に進めました。
・①：1章から解き解説を丁寧に読む。コードを書きながら。(模擬試験は除く)
・②：また、1章から解く。(模擬試験は除く)
・③：2週目で間違えた問題を解く。解説を読み丁寧に理解する。(模擬試験を除く)
・④：模擬試験1つめ
・⑤：模擬試験2つめ
これ以降は、模擬試験を繰り返しときます。
答えを覚えてしまっているかもしれませんが、問題ないです。なぜ正解か説明できればいいです。

解くとわかりますが、模擬試験を解く前はそれまでの章を完璧にした！と思って模擬試験に挑みますが正答率は50%程度。
正直、まじか...無理かもな...って感じでした。

しかしここで諦めるのはマジでもったいないです。
なぜなら、実際の試験はこの模擬試験の類題が結構な割合で出るからです。


### 勉強期間
2024/2～2024/4の約2か月

### 学習スケジュール
【平日】3時間ちょい
朝：90分
昼：40分くらい
夜：60分

【休日】6時間くらい
午前：3時間
午後：3時間

自分は量をやることにこだわりました。
呑み込みがよくないというのはありましたが、量をやれば自分の勉強の質が良いか悪いかが分かるからです。
逆に量をやってないのに、質を重視するというのは自分的には量をこなせないから質という言い訳に逃げていると感じてました。
意識高いこと言っててきもいですが、割と本心でそう思ってやってます。
質はたくさんの量をこなした後に考えればいいんです！


### 最後に
ここまで偉そうに語ってきましたが、結局はこの黒本を極めるということです。
この記事が少しでもJava Silverの受験を考えている方の助けになればいいなと思います。
次は、Java Gold SE11の合格体験談について書いていこうかなと思います！
Yao's Garbled Circuit

# やり方
Binary なサーキットがあるとする。このサーキットを 2-Party, P1 と P2 で評価する。

```
   Circuit:
             0|
            (2:Or)
          1/      2\
       (0:And)    (1:Or)
       3/   4\   5/    6\
Input: 0      1  2       3
```

サーキットの構造は P1 と P2 が共有する。
P1, P2 の入力は、お互い公開せずにサーキットを評価する。
サーキットのどの入力を、どちらが提供するのかは事前に決めておく。

## Step 1: P1 がサーキットを作る
サーキットの各ワイヤー (上の図の `|` の部分) について、P1 が True と False に対応するワイヤーラベルを作る。

ワイヤーラベルには、ランダムな鍵とランダムなパリティービットを割りあてる。パリティービットは、True と False のラベルで異なるようにする。

```rust
WireLabel {
  key: Vec<u8>,
  parity: bool,  
}

Wire {
  true_label: WireLabel,
  false_label: WireLabel,
}
```

### Garbled Tableの作成
サーキットの各ゲート (上の図の `(n: And/Or)` の部分) について、Garbled Table を作る。

Garbled Table は、ゲートの入力の全パターンに対応する値を持っている。
また、各値がどの入力パターンに対応するものなのかが分からないように、ランダムに割り当てられたパリティー値から作られるインデックスに格納される。

各値は、以下の様に作る。

```rust
lhs = Hash(wire_label_left.key || wire_label_key.right || gate_id)
rhs = wire_label_out
lhs XOR rhs  // 値
```

例えば、OR のゲートで、入力が、左が `false`, 右が `true` の場合は、結果が `true` になるので、`wire_label_left`には、左のワイヤーの `false` のワイヤーラベル、`wire_label_right`には、右のワイヤーの `true` のワイヤーラベル、`wire_label_out` には、`true` のワイヤーラベルを使う。

格納するインデックスは、

```rust
index = wire_label_left.p << 1 | wire_label_right.p
```

### Output Decoding Table の作成
また、評価結果を鍵からデコードするために、`Output Decoding Table` を作る。

```rust
lhs = Hash(wire_label_out.key || "out" || gate_id) % 2 as bool
rhs = value  // true または false
lhs XOR rhs
```

rhs は 1 ビットなので、lhs は最後のビットだけ残す。

## Step 2: P1 が P2 に、Garbled Table と Output Decoding Table を送る。
P1 が、各ノードの Garbled Table と、Output Decoding Table を P2 に送る。

## Step 3: P1 が P2 に自分の入力に対応するワイヤーラベルを送る
P1 は全てのワイヤーラベルを持っているので、自分の入力に対応するワイヤーラベルを P2 に送る。

## Step 4: P2 が Oblivious Transfer を使い、P1 から、自分の入力に対応するワイヤーラベルを取得する
### Oblivious Transfer (OT)
一番簡単な、Semi Honest な OT で、P2 が P1 からワイヤーラベルを取得する方法は、以下の通り：
1. 鍵ペアを 2 つ作って、片方の秘密鍵を捨てる
1. 自分が必要な方の入力に、秘密鍵が存在する公開鍵を、自分が必要でない方の入力に、秘密鍵が存在しない公開鍵を割り当てて、P1 に送る
1. P1は、true と false のワイヤーラベルを、受け取ったそれぞれに対応する公開鍵で暗号化して、P2 に送る
1. P2 は、必要な方のワイヤーラベルを秘密鍵で復号化する

## Step 5: P2 が Garbled Table を使い、サーキットを評価する
この時点で、P2 は全ての入力に対応するワイヤーラベルを持っているので、入力が接続されているゲートからルートのゲートに向かって、サーキットを評価する。

### ゲートの評価
ゲートの入力に対応するワイヤーラベルのパリティービットから、`Garbled Table` のインデックスを計算して、値を取得する。

```rust
index = wire_label_left.p << 1 | wire_label_right.p
```

次に、ゲートの入力に対応するワイヤーラベルから `lhs` を求める。

```rust
lhs = Hash(wire_label_left.key || wire_label_key.right || gate_id)
```

値は、lhs XOR `出力のワイヤーラベル` なので、値に `lhs` を XOR することで `lhs` を打ち消して `出力のワイヤーラベル` を取得する。

## Step 6: P2 が、ルートゲートの出力ワイヤーラベルをデコードする
`Output Decoding Table` の値は、`lhs` `XOR` `サーキットの評価結果` なので、
`Output Decoding Table` の、出力ワイヤーラベルのパリティービットのインデックスから値を取得して、以下の様に `lhs` を計算して、値に `XOR` することで、サーキットの評価結果を取得できる。

```rust
lhs = Hash(出力ワイヤーラベル.key || "out" || gate_id) % 2 as bool
```

# 実装
https://github.com/exfinen/crypto-playground/blob/master/src/protocols/yao_gc.rs

# 参考文献
- [Pragmatic MPC](https://securecomputation.org/)
Swift金額をカンマ区切りでフォーマットする方法

金額などで使用できる、カンマ区切りでフォーマットする方法です。

```.swift

    func formatToCurrency(amount: Int) -> String {
        let numberFormatter = NumberFormatter()
        numberFormatter.numberStyle = .decimal // 小数点以下やカンマ区切りを指定
        numberFormatter.groupingSeparator = "," // カンマをグループセパレーターに設定
        return numberFormatter.string(from: NSNumber(value: amount)) ?? "0"
    }

```

簡単にカンマ区切りすることができました。

![Simulator Screenshot - iPhone 16 Pro - 2025-01-19 at 08.31.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/eaef022c-b2e5-1bc5-8518-937bea699de0.png)
システム開発における『RFI』とは？発注者とベンダーの観点でまとめてみた

# はじめに

エンジニアのみなさま、日々の学習お疲れ様です。
また本記事まで足を運んでいただき本当に感謝です。

案件でRFIの回答依頼をいただきました。
RFIそのものの理解や対応方法について理解を深めるためにアウトプットしていきます！


# RFIとは？
**RFI（Request for Information）** とは、**情報提供依頼書** のことで、発注者がベンダーに対して製品やサービスの情報を収集するための文書です。システム開発においては、具体的な要件定義や発注を行う前に、市場の技術動向や各ベンダーの対応能力を把握するために活用されます。特に、新しい技術の導入や複雑なシステムを構築する際には、適切なベンダー選定のための重要なステップとなります。


# RFI作成の目的
システム開発におけるRFIの主な目的は以下のとおりです。
- **市場にどのような技術やソリューションが存在するのかを把握する**
- **ベンダーの技術力や提供可能なサービス範囲を確認する**
- **システム要件を固める前の情報収集を行う**
- **プロジェクトの実現可能性やコスト感を把握する**
- **複数のベンダーを比較し、適切な発注先の候補を絞り込む**
- **新規技術の導入に関するリスクや課題を明確にする**
- **将来的な拡張性や保守性を考慮した設計のための情報を得る**


# RFPとの違い

さまざまな記事でたくさん取り上げられていますが、**RFP（Request for Proposal）** と呼ばれる **提案依頼書** との違いを比較してみました。

| 項目       | RFI（情報提供依頼）            | RFP（提案依頼）            |
|------------|--------------------------------|-----------------------------|
| 目的       | 情報収集・市場調査            | 具体的な提案の取得          |
| 発注の段階 | 初期調査・計画段階            | 発注前の選定・評価段階      |
| 提出内容   | 技術情報、製品仕様、概算費用 etc  | 具体的な提案、見積、契約条件 etc |
| 回答の自由度 | 高い（ベンダー側が自由に提供） | 低い（指定された要件に基づく） |
| システム開発での適用 | 要件定義前の調査や技術選定に活用 | 開発パートナーの選定に活用 |

# 『発注者』の観点で見る作成のポイント
記事を何個か見てると、発注者がRFIを作成する際には、以下のポイントを意識する事が多い印象です。
- **目的を明確にする**
    - どの技術やソリューションについて情報を求めるのかを具体的に示す
    - どこに課題を感じているかを具体的に示す
- **簡潔にする**
    - 必要最小限の情報を求めることで、回答率を高める
    - 詳細を記載してしまうとベンダーの回答も難しくなり、期待する回答が得られない
- **回答フォーマットを指定する**
    - ベンダーごとのばらつきを防ぎ、比較しやすくする
- **公平性を保つ**
    - 特定のベンダーに偏らないように質問を心がける
- **プロジェクトのスケジュールや期待する納期感を伝える**
    - ベンダーが適切に対応できるよう情報を提供する


# 『ベンダー』の観点で見る回答のポイント
ベンダーがRFIに回答する際のポイントをまとめました。
**『ホームページに掲載されている以上の情報を丁寧に回答する』** ことを心掛けます。
- **簡潔かつ分かりやすく回答する**
    - 発注者が比較しやすいようにする
    - QAの一覧を冒頭に書き、本当に伝えたい内容はピックアップして詳細を記載する
    - 詳細を記載した場合、QAの一覧に対象ページを追記する
- **自社の強みを明確に伝える**
    - 他社と差別化できるポイントを強調する
- **類似案件の実績や事例を提示する**
    - システム開発の信頼性を高めるために、過去の実績を示す
    - 単純に実績を並べず、RFIの課題や要望に則した実績を優先する
- **対応可能範囲を正確に伝える**
    - 具体的な技術スタックや開発フレームワークを明記する
- **費用感を明確にする**
    - 発注者から要請がある場合は概算見積を提示し、価格の構成要素を説明する
    - 概算提示のないRFIも存在する
- **開発手法やプロジェクト管理体制を示す**
    - アジャイル、ウォーターフォールなどの開発手法や開発チームの体制について説明する
- **質問項目があればまとめて提示する**
    - 発注者は数社まとめて対応をするため、発注者の負荷がかからない様に配慮する



# 参考記事

https://www.shift-jp.net/blog/rfi/

https://hibiki.dreamarts.co.jp/smartdb/learning/le-sp211111-3/#:~:text=RFI%E3%81%AB%E5%AF%BE%E3%81%99%E3%82%8B%E5%9B%9E%E7%AD%94%E3%81%AF%E3%80%81%E6%A4%9C%E8%A8%8E,%E9%A0%85%E7%9B%AE%E3%82%92%E4%BD%9C%E6%88%90%E3%81%97%E3%81%BE%E3%81%99%E3%80%82

https://monstar-lab.com/dx/solution/howto-rfi/

https://gptech.jp/articles/system-rfi-beginner/

https://www.cm-net.co.jp/blog/rfi-sample-word/


# おまけ

弊社のご紹介もさせてください！

### 「日本で一番エンジニアが成長できる会社を創る」

https://prum.jp/

### エンジニアリングの募集

https://www.wantedly.com/projects/1808638

### PM・Webディレクションの募集

https://www.wantedly.com/projects/1355235

### セールス・事業開発の募集

https://www.wantedly.com/projects/1792065

### コーポレート系の募集

https://www.wantedly.com/projects/1752874

### コンサルティングの募集

https://www.wantedly.com/projects/1794481

弊社メンバーは日々学習した内容をアウトプットしております！
少しでもご興味を持たれた方は求人を見てみてください！
ご応募もお待ちしております！

### 最後までご覧いただき、ありがとうございました！
paizaラーニングレベルアップ問題集の「足し算」をやってみた。

paizaラーニングレベルアップ問題集の[足し算](https://paiza.jp/works/mondai/d_rank_level_up_problems/d_rank_level_up_problems__arithmetic_substitution_op_1)をやってみました。
- - -
###### 問題
https://paiza.jp/works/mondai/d_rank_level_up_problems/d_rank_level_up_problems__arithmetic_substitution_op_1
- - -
###### C
```c
#include <stdio.h>

int main() {
	printf("%d\n", 1231 + 5178);
	return 0;
}
```
- - -
###### C++
```cpp
#include <iostream>
using namespace std;

int main() {
	cout << 1231 + 5178 << endl;
	return 0;
}
```
- - -
###### C#
```cs
using System;

class Program
{
	public static void Main()
	{
		Console.WriteLine(1231 + 5178);
	}
}
```
- - -
###### Go
```go
package main
import "fmt"

func main() {
	fmt.Println(1231 + 5178)
}
```
- - -
###### Java
```java
public class Main {
	public static void main(String[] args) {
		System.out.println(1231 + 5178);
	}
}
```
- - -
###### JavaScript
```js
console.log(1231 + 5178);
```
- - -
###### Kotlin
```kotlin
fun main() {
	println(1231 + 5178)
}
```
- - -
###### PHP
```php
<?php
	echo 1231 + 5178 . PHP_EOL;
?>
```
- - -
###### Perl
```pl
print 1231 + 5178, $/;
```
- - -
###### Python3
```py
print(1231 + 5178)
```
- - -
###### Ruby
```rb
p 1231 + 5178
```
- - -
###### Scala
```scala
object Main extends App{
	println(1231 + 5178)
}
```
- - -
###### Swift
```swift
print(1231 + 5178)
```
- - -
###### 出力結果
```
6409
```
「順番で取り出す」だけじゃないnext関数

next関数はイテレータの要素を順番に取得する時に使うと思っていましたが、条件に一致する最初の要素そのものを取得したい時にも使えるんだなぁと

# next関数の基本
```py
# イテレータを用意
numbers = iter([1, 2, 3, 4])

# nextで順番に要素を取り出す
print(next(numbers))  # 出力: 1
print(next(numbers))  # 出力: 2
```

# 「要素そのものを取り出す」という使い方
### リストから条件に一致する最初の要素を取得する
```py
students = [
    {'id': 1, 'sex': 'male', 'rank': 1},
    {'id': 2, 'sex': 'male', 'rank': 2},
    {'id': 3, 'sex': 'female', 'rank': 3},
    {'id': 4, 'sex': 'male', 'rank': 4},
]

# 条件に一致する要素を取得
result = next(
    (item for item in students if item['sex'] ='male' and item['rank'] >= 2),None)

print(result)
# 出力: {'id': 2, 'sex': male, 'rank': 2}
```

### next関数を使わない場合のコード
```py
result = None
for item in students:
    if item['sex'] ='male' and item['rank'] >= 2:
        result = item # next関数を使えばこの部分がいらない
        break
```

next関数を使用すると簡潔に書けるから良さそう
個人的な備忘録：Pythonのrequirements.txtとGoのgo.modが似ていると感じたので記事にしてみた

## はじめに
現在、受講中のITスクールで実施されているハッカソン形式のチーム開発において、バックエンドをGo言語で開発することになりました。

:::note warn
**チームメンバーの方と環境構築を進める中で、PythonとGo言語に少し似ている部分があると感じたため、調べてみることにしました。**
:::

本記事は、その内容を自分用の備忘録としてまとめたものです。***走り書き程度のメモとなりますが、何卒ご容赦ください。***

## 書こうと思ったきっかけ
私自身、今回のGo言語については十分な知識がないまま、同じチームの方々と開発環境を進めることになりました。

:::note info
***その中で、Go言語には`requirements.txt`に相当する依存管理システムとしてGo Modulesが存在することを知り、これを深掘りしてみようと思いました。***
:::

***Pythonにはある程度馴染みがあるため、Pythonとの関連性も踏まえながら、この記事にまとめてみることにしました。***

## Pythonの`requirements.txt`とは

`requirements.txt`は、Pythonプロジェクトで必要な外部ライブラリやパッケージを記録したファイルです。  

このファイルを使用することで、プロジェクトの依存関係を明確にし、再現性の高い環境構築が可能になります。

### 特徴

**パッケージのリスト化:**

- 必要なパッケージとそのバージョンをリスト形式で記載します。
- **例:**

```requirements.txt
Flask==2.0.1
requests>=2.25.1
numpy
```

**環境の再現性:**

`pip install -r requirements.txt`コマンドを使うことで、他の開発者が同じ環境を簡単に再現できます。

**管理の容易さ:**

プロジェクトの依存関係を一元管理でき、複数の開発者が参加する際やデプロイ時に便利です。

## Go言語の依存管理（Go Modules）

Go言語では、`requirements.txt`に相当する依存管理システムとして`Go Modules`が使われます。

### Go Modulesの特徴

**`go.mod`ファイル:**

- プロジェクトの依存関係を管理するファイルで、Go Modulesの中心です。
- **例:**

```go.mod
module myproject

go 1.19

require (
    github.com/gin-gonic/gin v1.8.1
    golang.org/x/crypto v0.10.0
)
```

**`go.sum`ファイル:**

依存関係のチェックサムを記録するファイルで、セキュリティや整合性を保つ役割があります。

**Go Modulesのコマンドとメリット**

Go Modulesを使用すると、簡単に依存関係を管理し、プロジェクトの再現性を高めることができます。

### **ここまでの簡単な整理**

ここまでの知識を自分なりに整理し、一度まとめてみます。

- **Python**:  
  - `requirements.txt` を使って手動でパッケージとバージョンを記録・管理。  
  - コマンド例:  
    ```bash
    pip install -r requirements.txt
    ```
  - シンプルな構成で依存関係を明示的に管理。

- **Go**:  
  - `go.mod` と `go.sum` を使って、依存関係を自動的かつセキュアに管理。  
  - 主なコマンド例:  
    ```bash
    go mod init
    go get
    go mod tidy
    ```
  - 自動的な依存管理とGOPATH不要の柔軟性が特徴。

### Pythonの`requirements.txt`とGo Modulesの比較
ここまでの内容を簡単に表形式で整理しました。参考になれば幸いです。

| 項目               | Python (requirements.txt)               | Go (go.mod)                                |
|--------------------|----------------------------------------|-------------------------------------------|
| **目的**           | 外部ライブラリや依存関係の管理           | 依存関係とバージョンの管理                 |
| **記載方法**       | テキスト形式で手動記述                  | コマンドで自動生成される                    |
| **依存関係の詳細管理** | 手動で記載する場合が多い                 | `go.sum`でチェックサムを管理                |
| **環境再現性**     | `pip install -r`で再現可能              | `go mod tidy`で再現可能                     |
| **管理の仕組み**   | 仮想環境（`venv`, `virtualenv`）推奨      | Go ModulesによりGOPATH非依存で管理          |

### **共通点**
- **目的**:  
  - 両言語ともプロジェクトの依存関係を管理し、再現性の高い環境構築を支援。
  
- **重要性**:  
  - 複数人での開発やCI/CD環境での活用において、再現性と一貫性を保つために欠かせないツール。

:::note warn
***どちらの方法も適切に活用することで、開発効率を向上させることができます。***
:::

## まとめ
最後まで読んでいただき、ありがとうございました。***今回の記事では、自分の中でも曖昧だった知識を改めて整理し、言語化する形でまとめてみました。***

:::note alert
**本記事の内容はインターネット上の文献などを参考に作成していますが、あくまで個人の備忘録としての位置づけです。その点をご了承ください。**
:::

これからも分からないことに積極的に向き合い、アウトプットを通じて理解を深めていきたいと思います。
2024年🐉の振り返りと2025年🐍に向けて

# はじめに
タイミングとして少し遅い気がしますが、2024年を振り返って、2025年やりたいことをバーッと残しておこうと思います。KPTのフレームワークでKep,Ploblemが2024年の振り返り、Tryが2025年に向けてになります。一応2024年1年を振り返り対象としていますが、上期は忘れている部分も多いので、主に下期の話になります。
2024年1月に組織が変わり、自分の立場も少し変わり、不安な中でスタートしましたがなんとかやり切ることができ、多くのことを経験できました。
[2024年4月時の記事](https://qiita.com/taaaoi/items/34396de9177bec5b59e9)

# Keep
## 開発
- 必達案件を個人としても、チームとしても完了させることができた
- バッチの実装を初めてできた
- 自チームだけでなく、SREチームと連携して開発できた
- 対応チケット数が上期より、下期で増えた
- コンサルから来る案件依頼を検討し、滞留を減らせた
- 機能廃止案件を対応した

## 問合せ対応
- ほとんどの問合せに遅くても2,3日の滞留で着手、反応できた
- 長くボールを持ちすぎないことを意識して、コミュニケーションをとりながら対応を進めた
- 滞留最低ラインの10件は、開発締めのタイミング以外は守れた
- 振り返り時間を作って、チーム同士で事象の共有を行った
- 相談時間を毎日とることで、一人で抱え込みすぎないよう意識した
- 上期と下期でチーム内の運用方法を変えたことで、メンバーの偏りを改善し、機能知識定着を進められた
- 開発として何を解決するべきか、確認するべきかを考え、フロントとコミュニケーションをとりながらお客様の課題解決を最優先できた
- インシデント対応を経験した

## その他
- カジュアル面談の担当をし、社外のエンジニアとコミュニケーションをとれた。(弊社魅力は伝わったか？？)
- インターンシップの選考官を対応し、学生から楽しかったと好評だったこと。個人的にもモチベーションが上がった
- ユーザー会のようなイベントに参加し、開発代表として機能の説明を行ったこと。緊張したがユーザーの意見や反応を見ることができた
- スクラムマスターの資格を取得した
- チームイベントを振り返りながら、改善したり、不要なものは無くしたりした
- 外部イベントに参加してみた
- 体調管理ができていた(睡眠、運動)

# Ploblem
## 開発
- レビューの確認不足で防げたはずの不具合を起こしてしまった
- コードを書く時間が減ってしまった(実装、学習)
- チーム開発を取組む予定だったが、着手できなかった
- テストのない実装や見づらいコミットを拒否できなかった
- スケジュールに対するコミットが弱かった

## 問合せ対応
- 機能の認識間違いを起こし、フロントに誤った情報を提供してしまった
- 一部機能について知識不足によって、チーム内だけで解決できなかった
- 他チームから依頼がきた案件について、前提情報を確認するコミュニケーションが不足していたため、解決に必要以上の時間をかけてしまった

## その他
- 週次、月次で振り返りを行っているが、次のアクションに繋がっていない
- 自己学習の時間が減っている
- もう少しチーム内で気軽なコミュニケーションを増やしたい

# Try
## 開発
- スケジューリング、見積もりを行う。元々やっていたが、あまりに差し込み対応が多く予定を守れないことでなあなあになってしまっているので、復活させてやり方を見直す
- コミット単位がわかりずらいPRは拒否する
- デグレードを減らすための取り組みを行う
- ソースコードの書く時間を増やす(業務外含む)

## 問合せ対応
- 知識定着が進んでいない機能について学習を進め、緊急度高対応に備える
- ペア作業でデバッグをして、自走して問題特定できるとこまで伴走する
- 問合せを減らすための、Q&A作成やリファレンスの更新をアクションをとる

## その他
- チームイベントの担当者を決めて、オーナーシップを高めメンバー全員でイベントの改善を行う
- チーム運営について自動化できる部分を自動化することと数値をとれるようにする
- MGR業務を担当する
- チーム、グループを超えたプロジェクトに参加し、仕事の幅を広げることと顔を広める
- 興味がある社外イベントに参加する
- Qiitaに月１本は投稿する

# さいごに
2024年は2020年に入社して以降最も成長することができた年でした。役割が変わったことで視座が上がり個人の成果以上にチームの成果を考えるきっかけになりました。まだチームの事を考えるより、個人としての成果にコミットした方がいいのでは？と最初のほうは思っていましたが、やってみるとチームのことを考えることが楽しく、自分の強みであることに気がつくことができました。
先日、部署内で個人の成果を発表する会があったのですが、定量的に見てもチームのアウトプットがあがっていて成長していることを感じることができました。またメンバーそれぞれが自分の成果だけでなくチームの成果を意識して日々業務に取り組んでいたことが個人的には嬉しかったです。
2025年も個人としてもチームとしても成長し、楽しく働いていきたいです！
タイルの実体は、印刷された１図葉の地図ではないか？

## はじめに
タイトルのようなことを漠然と考えてみたので、言語化を試みます。

## タイルと紙地図

Web 地図は紙の地図と異なる体験をもたらしてくれます。１枚１枚の図葉に分かれている紙地図とは異なり、地図タイルを用いた Web 地図では、自由にスクロールできるシームレスな地図を体験できます。しかしながら、地図タイルと紙地図は全く異なるものではないと思います。

**「タイル」という概念は、空間の区切り方**で、地域メッシュや地形図図郭等に相当する概念となるでしょう。すると、生成された**１枚１枚のタイルの実体は、１枚の地図**（例えば『2万5千分1地形図「東京首部」』といったもの）に相当します。

紙地図は縮尺と図郭によって各図葉に分割されています。地図タイルもズームレベルとタイル図郭によって各々のタイルに分割されています。１枚のタイルも分割された１つの図葉と考えることができます。

## タイルと印刷術

紙の地図は、限られた紙面上にどのように地図情報を書き込むのか、という点が重要となります。印刷技術により、出せる精度や色の制約があります。すべての情報を１つの紙面に描き込むわけにはいかないので、精度・情報密度と表示範囲のトレードオフに応じて、例えば、「500万分1日本とその周辺」や「20万分の1地勢図」、「2万5千分1地形図」というように目的に応じた様々な種類の地図が出ているわけです。

タイルが活躍する Web 地図においては、様々な情報を重ね合わせたり、隣接する地域や縮尺のデータをシームレスに表示することができます。利用者が地図の内容を変更することもできます。紙の地図に比べて、物理的な制約が大きく緩和され、見やすく、高度な使い方ができるようになっています。

ただし、これは「Web 地図としての話」です。Web 地図は、シームレスな地図を実現するために、利用者の求めに応じて、１枚１枚の地図（すなわちタイル）を必要なだけ順次呼び出し、場合によっては加工して、最後に貼り合わせるように画面に表示します。要求が変われば、同様に順次画面の更新も行います。

しかし、呼び出される１枚１枚のタイルはというと、これは**単にタイル図郭によって区切られた１枚の地図**なのです。タイルという図郭の考え方やタイルのデータの持ち方というのは、Web 地図用に工夫されていますが、それ以外は他の地図と変わりません。

よく使われているラスタタイルは 256 px や 512 px 四方の画像データですし、ベクトルタイルの代表格である Mapbox Vector Tile 形式は一定精度の内部座標を持っています。つまり、よく使われているタイルのデータ形式上は、内部の座標値の精度に限界があるわけです。Web 地図で利用することを考えると、パフォーマンスを維持するために、１つのタイルのファイル容量にも限度があります。

そのため、１つのタイルにどのような情報を書き込むかを考えると、ズームレベル（縮尺）に応じた精度で、Web 利用に耐えうる情報量の限界内で地図の情報を出力する必要があります。これは、紙面の大きさと印刷技術の限界内で地図情報を出力する紙地図にも通じる考えです。

そう考えると、**タイルは、地図の「印刷結果」の一形態**と言えるかもしれません（もしくは、地図印刷の応用としては、タイルができたのかもしれません）。ある地図のデータベースがあって、それを紙の地図に出力するか、タイルに出力するかは、縮尺と図郭と媒体の違いによるレパートリーとなるでしょう。

デジタルなタイルとアナログな紙地図ですが、作成時に求められることは共通していると思われます。タイル１枚１枚は、本質的に１図葉の地図であり、紙地図の時と同じような地図編集等の考え方や技法が利用できますし、利用すべきでしょう。


## 参考とした記事

本記事のアイデアのベースとなった記事を紹介します。

以下は、タイルを１図葉の地図として使おうというアイデアです。

* [ベクトルタイル一枚をCMSにおけば管内図基盤なのではという話をあとで書く](https://qiita.com/hfu/items/0f1acf480300b1f430e6)
* [神戸市「地域の範囲」データを２枚のベクトルタイルにする](https://qiita.com/hfu/items/7e9250e99006b7b1c694)

以下の記事では、タイルにまつわる難しさとして、タイルが「印刷術」であることを指摘しています。

* [ウェブ地図の多様性と、ベクトルタイルで人を助けること](https://qiita.com/hfu/items/c0c496edc07beabdd22c)

> ベクトルタイルって、**地図そのものではなく、地図の印刷術**であるのだ、というところが難しいのだと思います。地図そのものと比較して、一段メタなのです。


## おわりに

図書室や資料庫にお邪魔したときに、地図作成に関する古い本を発見することがあります。スクライブが最新技術として掲載されていれば良いレベルの本です。当然、Web 地図のことなど書いてあるはずがないのですが、一方、タイルは「印刷された１図葉」であるという発想に立つと、そういう本にこそ、現在の Web 地図にとっても大事なことが書かれているような気がします。温故知新ですね。あいにく手元にそのような古い本はないのですが、次、そのような本に出会うのが楽しみです。
paiza.ioでelixir その339

# 概要
paiza.ioでelixirやってみた。
Streamに、なじめないので、訓練してみた。
Stream見つけたので、やってみた。

# 参考にしたページ

https://qiita.com/kikuyuta/items/c214b75df1fca947bc4e

# サンプルコード

```

defmodule Password do
    def gen(len, l, u, n, s) do
        if len >= l + u + n + s do
            base_str()
            |> Enum.reduce("", & &2<>&1)
            |> random_stream()
            |> Stream.reject(&(&1 in ambiguous_chars()))
            |> filter(len, l, u, n, s)
            |> to_string()
        else
            raise ArgumentError, message: "The length must equals to or be greater than the sum of the numbers of each letter types."
        end
    end
    def ambiguous_chars() do
        String.split("0oO1iIjJlL9qQ", "", trim: true)
    end
    def filter(str, len, l, u, n, s) do
        str_list = Enum.take(str, len)
        if (base_str()
            |> Enum.map(& Enum.count(str_list, fn s -> 
                s in String.split(&1, "", trim: true) 
            end))
            |> Enum.zip([l, u, n, s])
            |> Enum.map(fn({x, y}) -> 
                x >= y 
            end)
            |> Enum.all?)
        do
            str_list
        else
            filter(str, len, l, u, n, s)
        end
    end
    def random_stream(str) do
        Stream.unfold(nil, & {random_char(str), &1})
    end
    defp random_char(str) do
        Enum.random(String.split(str, "", trim: true))
    end
    def base_str() do
        str_lower = "abcdefghijklmnopqrstuvwxyz"
        str_upper = String.upcase(str_lower)
        str_number = Enum.to_list(0..9) 
            |> Enum.map(& Integer.to_string(&1)) 
            |> Enum.map_join(& &1)
        str_special = "-/"
        [str_lower, str_upper, str_number, str_special]
    end
end

Password.gen(8, 2, 1, 1, 0)
|> IO.inspect





```

# 実行結果

```
"phk2z3TU"
```

# 成果物

https://paiza.io/projects/BHLS697Znk45Hk8MYuvguA?language=elixir


以上。
(その1).構造体で遊ぶ。(基本形)


x M5NanoC6での予定は、未定

目的
cの構造体をとりあえず使う


いろいろ
各種、電文(パケット(フレーム))にデータを
押し込むには、基本操作なので思い出す。
ここ、5年から10年は、使っていない
基本、ショートパケットが好みなので
機能番号、型、データ(8バイトぐらい)のパケットで
用を済ますから
なぜか、ロボットの人たちは、ロングパケットを多用して項目を押し込んで
1回で転送するのが多い?
いちお、競技プログラミングでもよく出る、データ構造の問題らしい?
難易度が高いらしい?
難易度が高いと逃げるやっが増えるので、アクセスカウンターが回らないが
いいか!!!
逆に各種、問題に出やすい。(だから?)


オンラインコンパイラ


```c++


#include <iostream>
using namespace std;
int main(void){
    // Your code here!
    printf("START\n");
    
    struct {
        int sw1;
        int sw2;
    } SWs;
    
    SWs.sw1 = 1;
    SWs.sw2 = 2;
    
    printf("sw1=[%d]\n",SWs.sw1);
    printf("sw2=[%d]\n",SWs.sw2);
    
}//main


```


```

START
sw1=[1]
sw2=[2]

```
paiza.ioでelixir その338

# 概要
paiza.ioでelixirやってみた。
Streamに、なじめないので、訓練してみた。
AtCoderやってみた。

# 参考にしたページ

https://qiita.com/zacky1972/items/4f6782794f50d91196e4

# サンプルコード
abc333_c
```
defmodule Main do
  def main() do
    n = IO.read(:line)
        |> String.trim()
        |> String.to_integer()
    Stream.unfold([1], fn a ->
        l = for p <- a, q <- a, r <- a  do
            p + q + r
        end
        |> Enum.uniq()
        |> Enum.sort()
        {l, [hd(a) * 10 + 1 | a]}
    end)
    |> Stream.drop_while(fn l -> 
        Enum.count(l) < n 
    end)
    |> Enum.take(1)
    |> List.flatten()
    |> Enum.at(n - 1)
    |> IO.puts()
  end
end

Main.main()

```

# 実行結果
5
```
113
```

# 成果物

https://paiza.io/projects/ahnc90IK6BUk6eZfkrcs6w


以上。
paiza.ioでelixir その337

# 概要
paiza.ioでelixirやってみた。
Streamに、なじめないので、訓練してみた。
AtCoderやってみた。

# 参考にしたページ

https://qiita.com/zacky1972/items/52532477b8df160d5f97

# サンプルコード
abc334_b
```

defmodule Main do
  def main() do
    [a, m, l, r] = IO.read(:line)
        |> String.trim()
        |> String.split(" ")
        |> Enum.map(&String.to_integer/1)
    [first_tree_pos] = Stream.unfold(l, fn x -> 
            {x, x + 1} 
        end)
        |> Stream.drop_while(fn x -> 
            rem(x - a, m) != 0 
        end)
        |> Enum.take(1)
    [last_tree_pos] = Stream.unfold(r, fn x -> 
            {x, x - 1} 
        end)
        |> Stream.drop_while(fn x -> 
            rem(x - a, m) != 0 
        end)
        |> Enum.take(1)
    IO.puts(div(last_tree_pos - first_tree_pos, m) + 1)
  end
end

Main.main()




```

# 実行結果
5 3 -1 6
```
3
```

# 成果物

https://paiza.io/projects/qDxrMWm_vJdVAX4XYGuH5g

以上。
個人的な備忘録：GOPATHが全くわからなかったので、理解を深めるために記事としてアウトプットしてみた

## はじめに
現在、受講中のITスクールで実施されているハッカソン形式のチーム開発において、バックエンドをGo言語で開発することになりました。

:::note warn
**これに伴い、Go言語を使用したバックエンドのDocker環境を構築することとなり、チームメンバーの方に丁寧に教えていただく機会がありました。**
:::

本記事は、その内容を自分用の備忘録としてまとめたものです。***走り書き程度のメモとなりますが、何卒ご容赦ください。***

## 書こうと思ったきっかけ
私自身、今回のGo言語については十分な知識がない中で、同じチームの方々と開発環境を進めることになりました。

:::note info
***その過程で「GOPATH」という概念が出てきたのですが、全く理解できていない状況だったため、学びを深めるために記事としてアウトプットしてみることにしました。***
:::

Pythonにはある程度馴染みがあるので、Pythonとの関連性も踏まえながら、この記事にまとめたいと思います。

## PYTHONPATHと似ていると感じた
「**環境変数として、プログラムが必要なリソースを探すパスを指定する**」という役割が共通している点で、PYTHONPATHとGOPATHは似ていると感じました。

**共通点**

- **環境変数**  
  - どちらもプログラミング言語の動作環境を設定するための環境変数です。

- **ソースコードの検索パス**  
  - いずれもプログラムや依存ファイル（モジュールやパッケージなど）をどこで探すかを指定します。

一方で、PYTHONPATHは自由度が高く柔軟に利用できるのに対し、***GOPATHは特定のディレクトリ構造を前提としたGoのビルド環境管理に使われることが分かりました。***

:::note warn
プログラミング言語ごとの違いを知るにつれて、さらに深く調べてみたいという気持ちが強まっています（笑）。
:::

## そもそも、GOPATHとは？

**GOPATH** は、Go言語でプログラムを開発する際に使用される環境変数の一つです。 

https://go.dev/wiki/GOPATH

Goツールチェーンが **ワークスペース**（Goコード、依存関係、およびバイナリファイルが保存される場所）を見つけるために使用されます。

---

### 主な役割

#### 1. コードの保存場所を指定する
- **GOPATH** で指定したディレクトリは、Goのソースコード（プロジェクト）が格納されるルートディレクトリとして機能します。
- 典型的には、`src/` 以下にコードを保存します。
  - 例: `GOPATH/src/github.com/user/project`

---

#### 2. 依存パッケージの管理
- **Goモジュールシステム（Go Modules）** 導入前:
  - GOPATH 内の `pkg/` ディレクトリに依存パッケージが格納されていました。
- **Go Modules 導入後**:
  - 現在では依存パッケージ管理に Go Modules が利用されるため、GOPATH の `pkg/` ディレクトリはあまり使用されなくなりました。

---

#### 3. ビルドされたバイナリの格納
- プログラムを `go install` コマンドでビルドすると、**GOPATH** 内の `bin/` ディレクトリにバイナリが格納されます。
  - 例: `$GOPATH/bin/your_program`

---

### 補足: GOPATHとGo Modulesの関係
- **Go Modules**:
  - Go 1.11 以降に導入された依存管理システム。
  - プロジェクトごとにモジュール（`go.mod` ファイル）を使用して依存関係を管理。
  - モジュールが有効なプロジェクトでは、`GOPATH` に依存せずにコードを管理可能。

- **GOPATHが必要な場合**:
  - 古いプロジェクトや Go Modules を利用していない場合に重要。
  - モジュール対応プロジェクトでは、`GOPATH` の役割は縮小しています。

https://zenn.dev/spiegel/articles/20210223-go-module-aware-mode

https://qiita.com/manabito76/items/2a2f99a131781b968360#:~:text=GOPATH%E5%A4%89%E6%95%B0%E3%81%AE%E4%BB%A3%E3%82%8F%E3%82%8A%E3%81%AB,%E3%81%A7%E7%AE%A1%E7%90%86%E3%81%97%E3%81%A6%E3%81%84%E3%82%8B%E3%80%82

## まとめ
最後まで読んでいただき、ありがとうございました。***今回の記事では、自分の中でも曖昧だった知識を改めて整理し、言語化する形でまとめてみました。***

:::note warn
**内容はインターネット上の文献などを参考にしつつ作成しましたが、あくまで個人の備忘録程度のものです。その点は何卒ご容赦ください。**
:::

これからも分からないことに積極的に向き合い、アウトプットを通じて理解を深めていきたいと思います。