OmniAICreator/Qiita-1.07M huggingface dataset:
GraalVMはどれくらい速いの？

## はじめに

前回、こんな記事を書いてみたのですが、GraalVMによるNative化はどれくらい速いの？と思ったので軽く検証してみました。

https://qiita.com/s_moriyama/items/26e8dc02f780a84c1523

## SnapStart + Warmup版

https://github.com/aws/serverless-java-container/tree/main/samples/springboot3/pet-store

このソースをベースに、X-Rayを有効にWarmupだけをだけを入れたバージョンで測定。

```diff_java
public class StreamLambdaHandler implements RequestStreamHandler {
    private static SpringBootLambdaContainerHandler<AwsProxyRequest, AwsProxyResponse> handler;
    static {
        try {
            handler = SpringBootLambdaContainerHandler.getAwsProxyHandler(Application.class);

            // we use the onStartup method of the handler to register our custom filter
            handler.onStartup(servletContext -> {
                FilterRegistration.Dynamic registration = servletContext.addFilter("CognitoIdentityFilter", CognitoIdentityFilter.class);
                registration.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*");
            });

+            PetsController controller = new PetsController();
+            controller.listPets(Optional.of(5), null);

        } catch (ContainerInitializationException e) {
            // if we fail here. We re-throw the exception to force another cold start
            e.printStackTrace();
            throw new RuntimeException("Could not initialize Spring Boot application", e);
        }
    }
```

1.16秒でした。
やはり、SnapStartのRetoreが結構時間かかります。

![スクリーンショット 2025-02-07 3.57.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894042/fa06cadf-1589-481d-ccb9-9a54732263b5.png)

## GraalVM版

次はこちらのサンプルにX-Rayを有効にしたソースで検証してみました。

https://github.com/aws/serverless-java-container/tree/main/samples/springboot3/pet-store-native

1.09秒でした。
処理自体は27ミリ秒と非常に高速ですが、Initialization前の環境作成？と初期化を含めるとそこまでの大差はないですね。

![スクリーンショット 2025-02-07 4.11.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894042/99230c96-6467-8128-3e23-6991fa7da18b.png)

## SnapStart + Warmup + -XX:CompileThreshold=2 版

`-XX:CompileThreshold`の説明は以下のサイトがとても分かりやすいですが、
メモリ上にローディングした.classファイルを更にNativeコードへコンパイルする回数の閾値みたいな設定です。

https://hironemu.hatenablog.com/entry/20100521/1274458107

コールドスタート時に２回対象のメソッドを呼び出すことで、SnapStart時にNativeコード化までしてしまおう！という方法。
（1回だと毎回動的コンパイルが走って逆に遅い模様。）

が、あまり結果は変わらず。

![スクリーンショット 2025-02-07 4.30.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894042/dfbbe3fe-33bd-81c4-ff63-51fad82e81d8.png)

## まとめ

結論は、GraalVMによるNative化が一番高速かもしれません。

今回の検証ではクラスローディング対応をしたバージョンと大きく性能差はありませんでしたが、ダミー呼び出しによるクラスローディングは複雑な処理の場合、すべてのクラスを網羅できない場合もあるかと思います。

ただ、SpringBoot＋GraalVMは未経験な私が少し触った感じですと、リフレクション周りであまり相性が良くない感じでしたので、`Micronaut`などのフレームワークを使うのが最適かなと思います。

https://micronaut.io/
PHPで「エスケープシーケンスの種類と使い方」の動作を確認してみた。

# 概要

PHPで「エスケープシーケンスの種類と使い方」の動作を確認してみました。
以下のページを参考にしました。

https://www.javadrive.jp/php/string/index4.html

# 実装

以下のファイルを作成しました。

```sample.php
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>PHPテスト</title>
</head>
<body>

<p>
<?php
echo "私の名前は\"本田\"です<br>";
echo '私の名前は\'近藤\'です';
?>
</p>

<pre>
<?php
echo "こんにちは！\nお元気ですか？";
?>
</pre>

</body>
</html>
```

以下のコマンドを実行しました。

```
$ php sample.php 
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>PHPテスト</title>
</head>
<body>

<p>
私の名前は"本田"です<br>私の名前は'近藤'です</p>

<pre>
こんにちは！
お元気ですか？</pre>

</body>
</html>
```

# まとめ

何かの役に立てばと。
React Context の再レンダリング挙動と影響範囲を見極める 

## 概要
React Context は、コンポーネントツリー全体に状態や関数などの値を渡すのに非常に便利な仕組みです。しかし、Context の value に状態（state）を渡す場合、その値が更新されると、その Context を参照している全てのコンポーネントが再レンダリングされるという挙動に注意が必要です。本記事では、その仕組みと対策、そしてベストプラクティスについて解説します。

## React Context と Provider の仕組み
React Context は、ツリー全体にデータを提供するための仕組みです。通常、以下のように Context を作成し、Provider コンポーネントで value を渡します。

```tsx
import { createContext, useContext, useState } from 'react';

const MyContext = createContext({
  count: 0,
  setCount: () => {},
});

export const MyContextProvider = ({ children }) => {
  const [count, setCount] = useState(0);
  return (
    <MyContext.Provider value={{ count, setCount }}>
      {children}
    </MyContext.Provider>
  );
};

export const useMyContext = () => useContext(MyContext);
```
この例では、count とその更新関数 setCount を Context に渡しています。

### Provider の Value が更新されると再レンダリングされる仕組み
React Context の特徴として、Provider の value が変更されると、その Context を参照しているすべてのコンポーネントが再レンダリングされるという点があります。

例えば、上記の例で setCount により count の値が変わると、MyContext を使用している全てのコンポーネントが再レンダリングされます。これは、Context の value が変化したことを検知し、依存しているコンポーネント全体に最新の value を伝えるためです。

## 再レンダリングが及ぼす影響と注意点
#### 影響範囲の大きい状態の場合
Provider の value に、アプリケーション全体で頻繁に変更される状態を含めると、以下の問題が発生する可能性があります。

#### パフォーマンスの低下
すべての消費側コンポーネントが再レンダリングされるため、不要な再描画が多発し、パフォーマンスに悪影響を及ぼす可能性があります。

#### 意図しない再レンダリング
再レンダリングが多くなると、意図しない副作用（例えば、スクロール位置のリセットや、フォームの入力状態が消えるなど）が発生する可能性があります。

#### コンテキストの value に渡すべき内容の見極め
Provider の value には、本当に複数のコンポーネントで共有する必要があるデータや関数のみを含めることが推奨されます。
例えば、あるコンポーネント固有の状態や、再レンダリングの影響が大きい処理は、Context ではなく個別のコンポーネント内やカスタムフックで管理するほうが望ましいです。

### React Context における再レンダリングと影響範囲の考察
React の再レンダリングは、状態や props に変化があった箇所のみが実際に DOM に反映される仕組みになっています。
そのため、Context の value に状態を渡す際も、実際に変更があった部分だけが再描画されるというメリットがあります。しかしながら、Context に渡す値が頻繁に変化する場合は、その Context を参照している全てのコンポーネントが再レンダリングされる可能性があるため、影響範囲を十分に考慮する必要があります。

## React の再レンダリングの仕組み
React では、状態（state）やプロパティ（props）が変更されると、その変更が発生したコンポーネントの関数が再実行され、新たな JSX が生成されます。その後、React の差分検出（Reconciliation）プロセスによって、実際に DOM に反映されるのは変更のあった部分のみとなります。
つまり、再レンダリング自体はコンポーネント全体が再評価されるものの、ユーザーに見える更新は必要な部分だけになるため、効率的に動作します。

### Context の再レンダリングと影響範囲
Context の Provider に状態を渡すと、その値が変わるたびに、その Context を利用しているすべてのコンポーネントが再レンダリングされます。
たとえば、以下のように Context に複数の状態をまとめて渡している場合：

```tsx
const MyContext = createContext({
  count: 0,
  text: '',
  // ・・・他の状態
});
```
count や text に変更があった場合、これらを参照している全コンポーネントが再レンダリングされます。
ただし、React の再レンダリングは変更のあった箇所のみを実際に更新する仕組みになっているため、必要な部分だけが更新され、パフォーマンスが最適化されています。

それでも、影響範囲を考慮して Context にどの状態を含めるべきかは慎重に検討する必要があります。
たとえば、頻繁に更新される状態や、コンポーネントツリー全体に広く影響する状態は、個別のコンポーネント内やカスタムフックで管理し、Context にはあまり渡さない方が望ましい場合があります。

## まとめ
React の再レンダリングは、変更があった箇所のみ更新される仕組みであり、無駄な描画は抑えられています。
しかし、Context に状態を渡す場合、該当する Context を参照するすべてのコンポーネントが再レンダリングされるため、更新頻度の高い状態は注意が必要です。
影響範囲を考慮し、必要な状態のみを Context に含める、または個別のコンポーネントやカスタムフックに分割するなどの工夫が求められると思います。
Windows でしか動かなくていいの

## CA1416 の警告がウザい
のでメモ。

### Windows でしか動作しないアプリなので良いいの！
メソッドごとは面倒なのでクラス毎まとめて指定しちゃう。
```
namespace FooBarApp
{
    [SupportedOSPlatform("windows")]    // <---これ
    internal class HogeHogeClass
    {

    // 以下略
```

新しいスタイルだと Program.cs に関数書かないんだけど！
という場合はこう書けばよろし。
```
if (OperatingSystem.IsWindows())   // <--- これ
{
    // なにかする
}

return 0;
```
プロジェクト（リポジトリ）をGitHubに反映したい

# 前置き
- ここでは特定の場合を除いて、「リポジトリ」を「**プロジェクト**」として書いています
- この記事はubuntuターミナル上で動かすことを想定しています
[ubuntuの入手はこちらから](https://jp.ubuntu.com/download)

## この記事の対象
この記事は、次の人を中心に想定して書いています。
- GitHubを初めて使った人
- GitHubは触っているが、既存のプロジェクトを新規でpushしたことがない人

## 上級者の方や使い慣れている方へ
　**自身の知識のアウトプットを兼ねて書いた記事です。もし、間違いや疑問があればコメントのほうから教えていただけるとありがたいです。適宜対応します。**

## 書かないこと
- GitHubの登録方法

# プロジェクトを新規作成
新しい Git リポジトリを作成
```
git init
```
※プロジェクトがもうある場合は実行しなくても大丈夫です。

# 変更をステージング
## ステージングとは
ステージングとは、修正を確定することだと認識しておいて間違いはないと思います。ペーパーテストでいえば、間違えている問題を解きなおして、箱に入れるイメージです。[^1]
※[GitHubからpullしていない人はこちら](#リモートブランチとの連携)

## ステージングの方法
ひとことでステージングと言っても、方法はいくつかあります。

- すべてのファイルをステージング
```
git add .
```

- 特定のファイルをステージング
```
git add [ステージングしたいファイル名]
```


# ファイル名が分からないとき

ファイル名が分からないときは、次のコマンドで状態確認をすることができます。
```
git status
```

## 実行例と結果例

```
user@name:~/directory$ git status # ここが実行例。下はすべて結果。
On branch main
Your branch is ahead of 'origin/main' by 1 commit.
  (use "git push" to publish your local commits)

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   index.html

no changes added to commit (use "git add" and/or "git commit -a")
```

### 解説

`On branch main`
この行は現在のブランチ名が書いてあります。（現在はmainブランチ）

--
`Your branch is ahead of 'origin/main' by 1 commit.`
`  (use "git push" to publish your local commits)`
ここは、現在コミットされているファイルの数が書いてあります。`1commit` と書いてある場合は、まだGitHub に反映できていないので、[ ここ ]の手順でpushしましょう。

--
```
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   index.html
```
`changes no staged for commit`
コミット前のステージングがされていないことを示しています。

`  (use "git add <file>..." to update what will be committed)`
変更をステージングするときは[ ここ ](#変更をステージング)のコマンドを実行します。

`  (use "git restore <file>..." to discard changes in working directory)`
作業ディレクトリ内の変更を取り消す場合は次のコマンドを実行します。
```
git restore [変更を取り消したいファイル名]
```


---
# コミットをする
## コミットとは

コミットとは、修正したデータを入れた箱を、閉じる段階です。
テストを第三者の機関に送る、出荷直前の段階です。
## コミットの方法

次のコマンドを実行することでコミットをすることができます。

```
git commit -m "feature/change-details"
```
※`change-details`の部分は変更内容を書いてください。

### 初めての場合
初めて（作りたて）の場合、いくつかの変更前に上のコードではなく、次のコードを実行しておきましょう。
```
git commit -m "Initial commit"
```

# ここからは初めての人のみの作業
## 主軸ブランチの変更
　ブランチについては、[こちら ](https://qiita.com/ko-tarou/items/1b97e8e6ec697c924e51)を参考にしてください。
　ブランチは通常、「master」がはじめの主軸のブランチになっています。今後の利便性を考えて、主軸ブランチを「main」に変更しておきましょう。次のコードを実行してください。
```
git branch -M main
```
`-M `オプション
　このオプションは`-m `と異なり、**既に`main `ブランチができていても上書きする**オプションとなっています。初期の頃はなるべく使用しないように注意してください。

## リモートブランチとの連携
git remote add origin https://github.com/your-username/your-repo.git

## 変更の適用
　リモートリポジトリ（GitHubなど）にも変更を適用したい場合、`git push -u origin main `を実行する必要があります。
```
git push -u origin main
```
---
　以上の作業により、GitHubに反映させることができます。これからはどんどん作業をして使い慣れていきましょう✨

[^1]: [後輩のためのGit講座（応用編）](https://qiita.com/ko-tarou/items/1b97e8e6ec697c924e51) written by @ko-tarou
MySQLの検索について

# 1.概要

今回SQLの検索を使用したので、基本的な構文と演算子まとめます。

# 2. SQLとは

SQL（Structured Query Language、構造化問い合わせ言語）は、データベース操作、管理を行う言語です。リレーショナルデータベース（RDB: Relational Database）に対して、データの検索、追加、更新、削除などをできます。

# 3. 検索

## 3.1 検索の基本

```SQL
SELECT
    カラム名
FROM
    テーブル名
;
```
- SELECTはFROMで選択したテーブルから、カラムを選択するものです。
- カラム名を選択すると選択したカラムのみ表示できます。
- [*]は全てのカラムを指定します。
- FROMは、対象テーブル名を指定します。

## 3.2 where

```SQL
SELECT
    カラム名
FROM
    テーブル名
WHERE
    カラム名 = '条件'
AND
    カラム名 != '条件' --否定
OR
    カラム名  BETWEEN 1000 AND 2000
;
```

- WHEREは、特定の条件に一致するデータを抽出する
- ANDは、両方の条件を満たす場合に検索する
- ORは、どちらか条件を満たす場合に検索する
- BETWEENは、範囲を指定して検索する
(BETWEEN 1000 AND 2000は、1000以上から2000以下までのものを検索する）

### 3.2.1 条件式

データの値を比較するための演算子です。

|演算子|	意味|	例|	説明|
|------|----|-----|------|
|=|	等しい|	age = 25|	age が 25 のデータを取得|
|!= または <>|	等しくない|	age != 25|	age が 25 ではないデータを取得|
|>|	より大きい|	age > 25|	age が 25 より大きいデータを取得|
|<|	より小さい|	age < 25|	age が 25 より小さいデータを取得|
|>=|	以上|	age >= 25|	age が 25 以上のデータを取得|
|<=|	以下|	age <= 25|	age が 25 以下のデータを取得|
---------------------------------------------

### 3.2.2 論理演算子

複数の条件を組み合わせるための演算子です。

|演算子|	意味|	例|	説明|
|-|-|-|-|
|AND|	両方の条件を満たす|	age >= 18 AND age <= 30|	18歳以上30歳以下 のデータを取得|
|OR|	どちらかの条件を満たす|	age < 18 OR age > 60|	18歳未満 または 60歳超え のデータを取得|
|NOT|	条件を満たさない|	NOT age = 25|	age が 25 ではないデータを取得|

### 3.2.3 特殊条件演算子

特定の条件を指定するための演算子です。
WHERE カラム名　特殊条件演算子の順番で使用します。

|演算子|	意味|	例|	説明|
|-|-|-|-|
|BETWEEN|	範囲内（開始値と終了値を含む）|	age BETWEEN 20 AND 30|	20歳以上30歳以下 のデータを取得|
|IN|	指定した値のいずれかと一致|	city IN ('Tokyo', 'Osaka', 'Nagoya')|	Tokyo, Osaka, Nagoya に住むユーザーを取得|
|LIKE|	部分一致（ワイルドカード検索）|	name LIKE 'H%'|	H で始まる名前を取得|
|IS NULL|	NULL のデータを検索|	email IS NULL|	email が NULL のデータを取得|
|IS NOT NULL|	NULL ではないデータを検索|	email IS NOT NULL|	email が NULL ではないデータを取得|

### 3.2.4 ワイルドカード

LIKE 句ではワイルドカードを使って部分一致検索ができます。

|ワイルドカード|	例|	説明|
|-|-|-|
|%|	name LIKE '%ar%'|0文字以上の任意の文字列が入る|
|_|	name LIKE 'H_n'|任意の一文字が入る|

## 4 ORDER BY

並び替えを行う。

```SQL
SELECT
    *
    カラム名
FROM
    テーブル名
ORDER BY カラム名　DESC
;
```
- DESC を指定すると降順（大きい順）、指定しない場合は昇順（小さい順）になる
- デフォルトは昇順になる

## 5 GROUP BY

GROUP BY は、データを特定の列ごとにグループ化して集計するために使用します。
集約関数と一緒に使用されます。

```SQL
SELECT
    カラムA, SUM(カラムB)　AS　合計
FROM
    テーブル名
WHERE
    条件
GROUP BY
    カラムA;
```

- ASは別名をつ指定する際に使用する
- SUMは合計を求める

|集約関数|例|説明|
|-------|-|----|
|COUNT|COUNT（カラム名）|レコードの数をカウントする|
|SUM|SUM（カラム名）|値の合計|
|AVG|AVG（カラム名）|値の平均|

GROUP BYがあると、全体の合計ではなく、カラムAのレコード事に合計が計算されます。


## 6 LIMIT

表示される列の数を制限する。
データを多い場合に使用する。

```SQL
SELECT
    カラム名, 集約関数
FROM
    テーブル名
WHERE
    条件
LIMIT
    10;
```
LIMIT 10　で10レコードまで取得できる。

## 7 最後に

SQL の基本的な検索や条件指定、グループ化、並び替えについて記述しました。GROUP BY や ORDER BY を適切に使うことで、データの分析や抽出を効率的に行えます。
ガウス過程の説明(スライド形式)

<br>

# ガウス過程について

![スライド2.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924643/71ff720c-471a-db77-ddb1-8e407f3f2a3b.jpeg)
![スライド3.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924643/a3e21dcd-3671-e95a-e513-3d74be25e728.jpeg)
![スライド4.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924643/576366d7-d250-e910-c747-3c93aae6f6e4.jpeg)
![スライド5.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924643/a0026433-3019-28de-cdec-2a3a70fcbb8a.jpeg)
![スライド6.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924643/d9e8deaf-faeb-45b3-8962-adda0cda8346.jpeg)
![スライド7.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924643/b56e5c2d-328c-2ab4-b217-cbb3b58bd24d.jpeg)
![スライド8.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924643/6071d225-58bb-3931-b878-4f07645d2981.jpeg)

![スライド9.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924643/0a4b4536-2d88-5aa6-7643-2b1804a265a6.jpeg)

<br>

# 精度を調べるため、ガウス過程を深層学習と比較

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924643/b8095197-492d-4244-9319-5b334c881ce1.png)



<br>

# 課題


![スライド11.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3924643/7bbf8ae4-166d-5635-3abf-31517d1f1781.jpeg)
GASで名前付き引数のfunctionをトリガー実行すると予期せぬ挙動になる

## 事象
例えば下記のfunctionをトリガー実行すると予期せぬエラーが起こる。

```
function hogehoge(offsetDays = -1) {
  Logger.log(offsetDays)
  const baseDate = new Date(); 
  baseDate.setDate(baseDate.getDate() + offsetDays); // offsetDaysを適用

  console.log(baseDate)

}
```

 #### トリガー実行時の結果の例
```
{month=2.0, hour=14.0, day-of-week=4.0, timezone=UTC, week-of-year=6.0, day-of-month=6.0, year=2025.0, authMode=FULL, second=5.0, minute=5.0, triggerUid=~~~~~~~}
```


## 解決策

```
function hogehoge() {
  offsetDays = -1 // ★ここに入れる
  Logger.log(offsetDays)
  const baseDate = new Date(); 
  baseDate.setDate(baseDate.getDate() + offsetDays); // offsetDaysを適用

  console.log(baseDate)

}
```

## 結論
トリガー実行するときは無名関数にしておいた方が安全で
Cursorでコスパ良く開発！LLM API比較と最適選択ガイド

# OpenAIとAnthropicのAPI料金比較

普段、Cursorを使用してコーディングしていますが、Proプランに加入しているに＿もかかわらず、月末には500回の使用制限に達してしまいます。そのため、APIを自前で登録して使用することになります。高精度な出力を得るため、これまで特に考慮せずにClaude 3.5 Sonnetを使用してきました。しかし、最近ではエージェントなどを利用する際にトークン数の消費が気になってきました。OpenAIからコスパが良いo3-miniなども出てきたで、この機会に費用感を調べて整理しようと思い立ちました。

Cursor：https://www.cursor.com/
Cursor pricing：https://www.cursor.com/pricing

## OpenAIのAPI料金

OpenAIは、複数のモデルを提供しており、それぞれに異なる料金体系があります。以下は、主要なモデルの料金です。

| モデル名           | 入力料金（$ / 1,000,000トークン） | 出力料金（$ / 1,000,000トークン） |
|--------------------|----------------------------------|-----------------------------------|
| GPT-4o             | $2.50                            | $10.00                           |
| GPT-4o mini        | $0.15                            | $0.60                            |
| o3-mini            | $1.10                            | $4.40                            |

出典元：https://openai.com/ja-JP/api/pricing/

:::note info
2025年2月12日時点 
以前に投稿していた内容に間違えがあったので修正致しました
:::


・GPT-4o: 高度なタスクに対応できる最強のモデルです。計算能力が高いため、コストは他のモデルよりも高めです。
・GPT-4o mini: より低価格で提供されるモデルで、日常的なタスクや軽い処理に適しています。
・o3-mini: コスト効率が良く、軽めのタスクに使用するのに適したモデルです。

## AnthropicのAPI料金
Anthropicは、「Claude」シリーズという言語モデルを提供しており、特に「Claude 3.5 Sonnet」は最も高度なモデルとして注目されています。以下は、AnthropicのAPI料金です。

| モデル名           | 入力料金（$ / 1,000,000トークン） | 出力料金（$ / 1,000,000トークン） |
|--------------------|----------------------------------|-----------------------------------|
| Claude 3.5 Sonnet  | $3.00                            | $15.00                           |
| Claude 3.5 Haiku   | $0.80                            | $4.00                            |
| Claude 3 Opus      | $15.00                           | $75.00         

出典元：https://www.anthropic.com/pricing#anthropic-api

:::note info
2025年2月7日時点
:::

・Claude 3.5 Sonnet: 高度なタスクに対応できるモデルで、OpenAIのGPT-4oに匹敵する性能を持っていますが、料金はやや安めです。
・Claude 3.5 Haiku: コストを抑えたモデルで、比較的軽いタスクに対応します。
・Claude 3 Opus: 最高級の性能を持つモデルで、最も高額な料金体系です。

## 結論
個人的な使用感ではo3-miniで十分に思えます。出力には満足ですし、かつ費用感も抑えてくれるので良しです。ただ出力に納得がいかない場合は、Claude 3.5 Sonnetに切り替えて出力するなどしています。出力結果を載せるなどをサボっている記事ですいません。時間があれば追記しておきます。
【ざっくりと理解するWeb技術入門】プロトコルってなんだ？

## 初めに

web周りの学習をし始めた時に必ず出てくる「プロトコル」
いろんな参考書や動画で **「通信における決まりごと」** と解説されるのを見かけます。

...決まり事？なんの...?（←最初にプロトコルの解説見た時の僕です）

この記事では、リアルな例を交えながら、初心者向けにプロトコルの概念を解説します！
ヒジョーにざっくりとイメージを掴むための内容ですので、厳格で正確な説明ではないことご了承ください。

---

## まずはイメージをざっくりと掴もう！

プロトコルとは「通信における決まりごと」と言いましたが、これを現実世界の例で考えてみましょう。

### ① 電話の会話ルール（諸説あるというかまぁ人によるが）

シーン：先輩に急ぎで電話して質問をしたい場合

1. **発信者Aさん**：「もしもし、○○です」（名乗る）
2. **受信者Bさん**：「もしもし、□□です」（名乗り返す）
3. **発信者Aさん**：「今大丈夫？」（相手の状況を確認）
4. **受信者Bさん**：「大丈夫だよ！」（応答）

### この時、何を発言するか、何を伝えるかは人間界の場合はそれぞれに委ねられています。
どういうことかというと、
いきなり「今日の晩ご飯はカレー！」とか言おうと思えば言えますよね。（仲のいい？先輩に限る）

### ですがコンピュータ世界やWeb検索においてはどうでしょう？
自分が望んでいない検索をブラウザに打ち込みますか？
サーバーから勝手に何かしらのデータ送られたいですか？

とまぁ、文脈のおかしな会話は辞めようねと。
このように **「お互いがスムーズにやり取りできるようにルールが決まっている」** というのがプロトコルの基本的な考え方です。

### ② 信号機のルール

道路を横断するとき、信号が **「赤」** なら止まり **「青」** なら進む、といったルールが決まっています。

もしこのルールがなかったら…

- ある人は「黄色だから進む」
- ある人は「黄色だから止まる」
- 車は「赤でも進む」

といった **カオスな状態** になってしまいます。

信号機のように **「みんなが共通のルールに従うことでスムーズに進む」** のがプロトコルの役割です。

---

## Webにおける具体的なプロトコルは？

では、コンピュータの世界ではどんなプロトコルが使われているのでしょうか？

### ① HTTPS（HyperText Transfer Protocol Secure）

みんなが普段使っている **ブラウザ（Google Chrome や Safari など）** は、Webサイトを表示するために **HTTPS** というプロトコルを使っています。

例えば、Googleで検索するとき、

```
https://www.google.com
```

と **「https://」** から始まっていますよね。
これは **「Webサイトを安全に閲覧するためのルール」** なのです。

ここでは簡単な説明にとどめますが、HTTPSの仕組みや機能の詳細など
気になる方はいろいろ調べてみると良いかと思います！
▼参考サイト

https://sales.fromation.co.jp/archives/10000067684

### ② その他のプロトコル

インターネットには **さまざまな用途に応じたプロトコル** があります。

| プロトコル名 | 役割・用途 | 例 |
|-------------|---------------------|--------------------------|
| HTTP        | Webページの通信      | Webサイトの閲覧         |
| FTP         | ファイルの送受信      | サーバーとのデータ転送  |
| SMTP        | メールの送信          | GmailやOutlookの送信機能 |
| POP3/IMAP   | メールの受信          | メールアプリでの受信    |
| SSH         | サーバーへの接続      | リモート作業           |
| DNS        | ドメイン名解決        | `google.com` → IPアドレス |

このように、それぞれ **目的に応じて異なるプロトコルが使われている** ことが分かります。

---

## まとめ

- **プロトコルとは「決まりごと」** のこと。
- **リアル世界でも「電話の会話ルール」「信号機のルール」などがプロトコルの一例。**
- **インターネット上では「HTTPS」「FTP」「SMTP」など用途ごとにさまざまなプロトコルが使われている。**
- **プロトコルがあるおかげで、世界中のコンピュータがスムーズに通信できる！**

プロトコルの理解が深まれば、ネットワークの仕組みがもっと面白く感じられるはずです！

---

## 補足

プロトコルとポート番号の関係について詳しく知りたい方は、以下の記事も参考にしてみてください。

https://qiita.com/arunbabababababa/items/909d2ba4bd275b180459
【ざっくりと理解するWeb技術入門】ポート番号ってなんだ？

## 初めに

Web技術を学び始めてすぐに
「ポート番号（Port Number）」というを目にすると思います。
よく部屋番号と比喩されて解説される記事を見かけますが、
それだけではイメージが掴めなかったので、より具体的な事例や比喩を交えて解説していきます。
（何となくでもイメージできるように知ることが目的のため、厳格や正確性に欠ける部分が生じます、ご了承ください🙇）

---

## まずはイメージをざっくりと掴もう！

ポート番号とは **「どのサービス、アプリケーションがどの通信を受け取るかを識別するための番号」** です。

### ① マンションの部屋番号と郵便受け

早速何言ってんだお前ってなりますよね、もう少しだけお付き合いください

マンションにはたくさんの部屋がありますが、それぞれ **部屋番号（101号室、202号室など）** が割り振られています。

郵便配達員が **「102号室の人に荷物を届けたい」** と思ったら、
- 住所（IPアドレス）でマンション全体を特定
- 部屋番号（ポート番号）で特定の人を識別

という流れで荷物を届けることができます。

このように、ポート番号は **特定のサービスを区別するための部屋番号** のような役割を果たしています。

### ② レストランの注文カウンター

レストランでは「受付窓口」が複数あります。
す○家を想定しましょう（レストラン...?）

- **注文カウンター（注文用、券売機とか）**
- **受け取りカウンター（料理の受け取り）**

それぞれ **異なる目的の窓口** があり、正しいカウンターを利用しないと適切な対応が受けられません。

コンピュータも同じように、
- **Webの通信（HTTP/HTTPS）はポート80/443**
- **メール送信はポート25**
- **リモート接続はポート22（SSH）**

といったように、異なるサービスごとに **決められたポート番号** を使っています。

---

## 少し踏み込んでみよう

ポート番号についてもっと詳しくなるために、以下の前提知識が必要です。
・IPアドレス
・プロセス

※少々の前提知識がある方向けの説明になるので、全くわからない場合はここはスキップしてください🙇

ネットワーク上で通信が発生する場合、IPアドレスの指定が必須でしたよね。
それがよく住所と例えられますね。
では先ほどの説明でした部屋番号ってなんでしょう...?
`住所であるIPアドレスだけで十分じゃね？`
と鋭い方は思ったかもしれません。



ここでも簡単な説明にとどめますが
### それぞれのアプリケーションを区別するためです。

例えば、
* Chromeでブラウザ検索して
* Icloudメールでメールのやり取りして
* Spotifyで音楽聞いて
と、同時にいろんなアプリケーションを利用するじゃないですか？

このそれぞれのアプリケーションの実行単位を`プロセス`といい
このプロセスに対しそれぞれポート番号を割り当てることで通信が正しくできます。

Chromeで検索して帰ってきたレスポンスがSpotifyに来たら困りますよね？（そもそも受け取れるようにはなっていないです、これもポート番号のおかげと言えますね）
という感じです

## いろんなポート番号を見てみよう

### ① よく使われるポート番号

| ポート番号 | プロトコル | 役割・用途 |
|-----------|-----------|-----------------|
| 80        | HTTP      | Webページの閲覧 |
| 443       | HTTPS     | 安全なWeb通信   |
| 21        | FTP       | ファイル転送    |
| 25        | SMTP      | メール送信      |
| 110       | POP3      | メール受信      |
| 22        | SSH       | サーバー接続    |
| 53        | DNS       | ドメイン名解決  |

このように、インターネットの通信は **適切なポート番号** を利用して行われています。

### ② ポート番号の分類

ポート番号は **0～65535** の範囲で定められ、以下のように分類されます。

- **ウェルノウンポート（0～1023）**：
  - 一般的なサービス用のポート（例：HTTP, HTTPS, FTP）
- **登録済みポート（1024～49151）**：
  - 特定のアプリケーションで使用（例：ゲームや専用ソフト）
- **ダイナミックポート（49152～65535）**：
  - 一時的な通信（例：PCからサーバーに接続するときのランダムなポート）

---

## まとめ

- **ポート番号は「どのサービス、アプリケーションが通信を受け取るかを識別するための番号」**。
- **マンションの部屋番号やレストランのカウンターのように、適切な窓口を通して通信が行われる**。
- **80番（HTTP）、443番（HTTPS）など、サービスごとに決まったポート番号がある**。
- **ポート番号は 0～65535 の範囲で、用途に応じて分類されている**。

ポート番号の仕組みを理解すると、ネットワークやサーバーの動きがより分かりやすくなります！

---

ポート番号について以下の解説記事が非常に参考になるので見てみてください。
▼参考記事

https://surfshark.com/ja/blog/what-is-my-port

https://qiita.com/t-furusato/items/0397459ecb39cecc2d81


## 補足

プロトコルについて詳しく知りたい方は、以下の記事も参考にしてみてください。

https://qiita.com/arunbabababababa/items/aa852d4084b1c3b8f748
【ざっくりと理解するWeb技術入門】Cookieとセッション

## はじめに

みなさん、こんな経験はありませんか？  

- 一度ログインしたら、次回も自動でログインされていた  
- ネットショップのカートに入れた商品が、ページを閉じても残っていた  
- 昨日検索した商品が、今日別のサイトの広告に出てきた 

実は、これらの仕組みの多くは **「Cookie（クッキー）」** という技術によって支えられています！  

また最近は多くのサイトでCookie許可を求めるものが多いため、よく見かけるのではないでしょうか
▼こんなのです
![cookiesample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4001794/75b0bc7e-1e44-8bb6-ee9e-871cc3b8d63b.png)


「Cookieってなに？」という初心者の方でも **超ざっくり理解できるように** 解説していきます！  
簡単のために厳格な解説や説明になっていない部分はご了承ください。

---

## 1. Cookieとは？

**Cookie（クッキー）とは、Webサイトがブラウザに保存する小さなデータ** のことです。  
サイトに訪れたときに **「この人は誰？」** を識別するために使われます。  
実際に個人情報レベルで特定するわけではなく、リクエストしているクライアントが誰かを識別するという意味です

▼リクエストがよくわからない場合はこちら

▼クライアントがよくわからない場合はこちら

---

## 2. Cookieの具体例

### **📌 例①：自動ログイン**
1. Amazonでログイン  
2. 次の日にもう一度Amazonを開いたら、ログイン状態が続いている  

💡 **これを実現しているのがCookie！**  
サイト側が **「この人は前回ログインしていた」** という情報をブラウザに保存しているのです。

---

### **📌 例②：カートの中身を記憶**
1. ネットショップでスマホケースをカートに入れる  
2. 途中でページを閉じる  
3. 次の日また開いたら、カートの中身がそのまま！  

💡 **Cookieのおかげで、カートの情報が消えない！**

---

### **📌 例③：広告の追跡**
1. 「スニーカー」を検索する  
2. 別のサイトの広告に「昨日見たスニーカー」が出てくる  

💡 **Cookieが「この人はスニーカーに興味がある」と覚えている！**  
（これが「トラッキングCookie」と呼ばれるものです）

---

## 3. Cookieの仕組み

ざっくりとCookieはこんな流れで動きます👇  

1. **サイトを開くと、サーバーがCookieを発行**  
2. **Cookieがブラウザに保存される**  
3. **次にサイトを開く際に、ブラウザが2.で保存したCookieをサーバーに送る**  
4. **サーバーが「前回と同じ人だ！」と認識する**  

---

## 4. セッションとは？

Cookieに似た仕組みとして **「セッション」** があります。  
大きな違いは **データの保存場所** です👇  

|  | **Cookie** | **セッション** |
|---|---|---|
| **データの保存先** | ブラウザ（ユーザー側） | サーバー |
| **保存期間** | 設定次第（数分～数年） | サイトを閉じるまで |
| **用途** | 自動ログイン、カート情報、広告 | 一時的なログイン認証 |

---

## 5. まとめ

- **Cookieは「ブラウザ」に保存するデータ**（ログイン情報、カート情報など）  
- **セッションは「サーバー」に保存するデータ**（短期間のログイン情報など）  
- **Cookieは便利だけど、セキュリティ対策も重要！**
統計検定DS発展の勉強　ー倫理・AI①ー

# AI全般
日本統計学会公式認定　統計検定データサイエンス発展対応　データサイエンス発展演習を学習した際の不明点のメモ．
「倫理・AIに関する基礎的な事項」のAI全般について．
## AIの活用領域
### 1. 物流
　物流拠点への人員配置に数理最適化手法が用いられている．
　2024問題に対し，シフトの最適化によってドライバーの休憩時間と輸送量を確保する取り組みが検討されたそう．
### 2. マーケティング
　Marketing Automation（MA）に用いられる．どの顧客にいつ，何を販売するのかを決定し，マーケティングキャンペーンを自動化する．
 自動化の対象は，
- マーケティング対象者の選定
- 宣伝する商品の選定
- 送信するメッセージの作成
- メール配信のタイミング
- SNS発信
:::note info
Enterprise Resource Planning(ERP)は，販売・配送・納品のプロセスの自動化を担う
:::
### 3.医療ー電子カルテ
　患者の医療記録を電子データにしてDBで管理する．マイナンバーを利用して，すべての医療施設でのカルテの共有を目指している．
### 4.地図
　地図上にデータを可視化する際には，データソースの信頼性が重要で，現実世界を正しく反映し，有益な情報を提供できるようにすることが大事．
- ベクタデータ：地点，線，多角形で表現. Shapefile, GeoJSON形式
:::note info
:star2:正確さ，複雑な表現 
:umbrella:高度な操作（プログラミング等），時間がかかる
:::
- ラスタデータ：地表をピクセルで分割し，各ピクセルに値をあてることで表現．csv形式
:::note info
:star2:地理上の隣接関係が分かりやすい
:umbrella:正確さに欠ける
:::
## AI系の用語
### 汎用AI（AGI）
あらゆるタスクに対応できる，人間のような汎用的な知能を持ったAI
### Convolutional Neural Network（CNN-畳み込みニューラルネットワーク）
画像データをメインとして，特徴抽出を行うニューラルネット．画像のピクセルから部分の特徴を抽出する畳み込み層，畳み込みを行った画像の次元を減らすプーリング層を中心に構成し，最後に各ピクセルを関数に入力することで出力を得る全結合層からなる
### Recurrent Neural Network(RNN)：時系列データを扱えるニューラルネット．自然言語処理や音声認識にも使われる．長期，短期の記憶を扱えるように忘却と選択を導入したLong Short Term Memory(LSTM)も存在する
### Generative Adverserial Networks(GAN-敵対的生成ネットワーク)：生成されたものの「本物らしさ」を学習しながら，高品質なデータ生成を実現
Generatorは受け取った乱数をもとにデータを生成する．
Discriminatorは本物（データセットに含まれている）に近いなら0,偽物であれば1を出力する．
```mermaid
graph LR
  B([Generator データ生成ネットワーク])-->|本物に似たデータを生成-騙す|C
  C([Discriminator 識別機])-->|本物か偽物かを判定する-見破る|B
 
```
###Transformer：自然言語処理において，Attentionを用いて単語間の関係性を抽出し次の単語を予測する深層学習モデル
<br>
<b>参考文献</b>
[1]日本統計学会. データサイエンス発展演習. 東京図書株式会社,2024
【ざっくりと理解するWeb技術入門】リクエストとレスポンス

## はじめに

Webを学び始めると **「リクエスト（Request）」と「レスポンス（Response）」** という言葉をよく聞くと思います。 
web開発をするうえで非常に大事な基礎知識ですが、
学び初めのころはすごく曖昧な理解やイメージがつかないポイントだと思います

この記事では、身近な例を使って **「リクエスト」と「レスポンス」** の仕組みをざっくりと解説していきます！  

極力難しい説明は排除し身近な例を使って説明をするので気軽に読んでいただけたらと思います🙌
（厳格な説明や表現ではないので、あくまでイメージつかむために参考にしてください）

---

## 1. 「リクエスト」と「レスポンス」とは？

**リクエスト（Request）** は「要求（リクエスト）」のこと。  
**レスポンス（Response）** は「返答（レスポンス）」のこと。  

Webの世界では、基本的に **クライアント（利用者側）** がリクエストを送り、**サーバー** がレスポンスを返す仕組みになっています。

### **📌 例①：「レストランでの注文」**
1. お客さんが **「ハンバーグ定食ください！」**（＝リクエスト）
2. 店員さんがオーダーを受けて料理を作る（＝処理）
3. 出来上がった「ハンバーグ定食」をお客さんに提供する（＝レスポンス）

この流れとWebにおけるリクエスト＆レスポンスの仕組みはほぼ同じです！  
「注文する（リクエスト）」と「料理が返ってくる（レスポンス）」がセットになっています。

---

## 2. Webのリクエストとレスポンスの流れ

次に、実際のWebでどのようにリクエストとレスポンスがやり取りされるのか見てみましょう。

### **📌 例②：「Googleで検索する」**
1. **ブラウザ（クライアント）** で「猫 かわいい」と検索する（リクエスト）
2. **Googleのサーバー** が「猫 かわいい」に関連するページを探す（処理）
3. **検索結果のページ** をブラウザに表示する（レスポンス）

💡 **リクエスト = 検索すること**  
（ハンバーグの例でいう注文）
💡 **レスポンス = 検索結果が表示されること**
（ハンバーグの例でいう料理が出されること）

---

## 3. リクエストの仕組みをもう少し詳しく！

リクエストには、いろいろな情報が含まれています。  
特に重要なのが「HTTPメソッド」と「ヘッダー」です。

### **✅ HTTPメソッドとは？**
リクエストには、「何をしたいのか？」を指定する **HTTPメソッド** があります。

| メソッド | 説明 | 具体例 |
|---|---|---|
| **GET** | データを取得したい | 検索、Webページを開く |
| **POST** | 新しいデータを送信したい | フォーム送信、ログイン |
| **PUT** | 既存のデータを更新したい | プロフィール編集 |
| **DELETE** | データを削除したい | 投稿削除 |

### **📌 例③：「Amazonで商品を探すシーン」**
1. 「スマホケース」を検索する（GET）  
2. 商品をカートに入れる（POST）  
3. カートの数量を変更する（PUT）  
4. 間違えたのでカートから削除する（DELETE）  

💡 **GET, POST, PUT, DELETE の動作を意識すると、Webの仕組みがわかりやすくなります！**

---

## 4. レスポンスの仕組みをもう少し詳しく！

サーバーが返すレスポンスには、「ステータスコード」と「データ本体」が含まれます。

### **✅ ステータスコードとは？**
レスポンスには **「処理の結果」** を表す **ステータスコード** がついています。

| ステータスコード | 意味 | 具体例 |
|---|---|---|
| **200 OK** | 正常に処理された | Webページが正しく表示された |
| **301 Moved Permanently** | 別のURLに移動した | 旧URLから新URLへリダイレクト |
| **400 Bad Request** | リクエストが間違っている | フォームの入力ミス |
| **401 Unauthorized** | 認証が必要 | ログインが必要なページ |
| **403 Forbidden** | アクセス権限なし | 管理者限定のページ |
| **404 Not Found** | ページが見つからない | URLが間違っている |
| **500 Internal Server Error** | サーバー側のエラー | Webサイトの不具合 |

### **📌 例④：「オンラインショッピングでエラーが出るケース」**
1. 商品ページが表示される（200 OK ✅）  
2. URLを間違えたら「404 Not Found ❌」  
3. サーバーが落ちていたら「500 Internal Server Error ❌」  

💡 **「あれ？サイトが見れない！」と思ったら、
ステータスコードをチェックすると原因がわかるかもしれません！
自分はこれ知ったとき少しワクワクしました...**

---

## 5. 【スキップ可】実際にリクエストとレスポンスを見てみよう！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4001794/5efc115d-f8b6-b421-453f-07818728369b.png)

画像では実際に当記事を編集する際に
僕のPC↔どこかのサーバーで行われている通信を見ています。

Ctrl+shift+iキーで開発者ツールを開き、
ネットワークタブを開くと画像と同じ画面が開きます。
そこで適当なファイルを選択すると、そのファイルが、
### どうやってリクエストされて
### どのようにレスポンスされたか
の通信の詳細がわかります！

なんだかかっこいいので是非お試しください

---

## 6. まとめ

- **リクエスト = クライアントからの要求（検索する、ログインするなど）**
- **レスポンス = サーバーからの返答（検索結果、ログイン成功など）**
- **リクエストのHTTPメソッドには GET / POST / PUT / DELETE などがある**
- **レスポンスにはステータスコード（200, 404, 500 など）が含まれる**

Webは **「リクエスト（要求）」と「レスポンス（返答）」のやり取り** で成り立っている！  
基本中の基本なので、絶対に頭に入れておくようにしましょう。

---
RayCast "Hyper Key"とは?

## Hyper Keyってなんだ??

v1.19.0で登場した新機能

https://www.raycast.com/changelog/1-91-0

> Put your unused keys to work with our new Hyper Key feature. Transform a single key, such as Caps Lock, into the Hyper Key, which combines all four modifiers: ⌃⌥⌘⇧. This additional modifier key enhances your keyboard shortcuts across all apps, serving as a lightweight companion for boosting productivity with Raycast and other applications.
> 
> To customize the Hyper Key, go to Settings → Advanced → Hyper Key.
> 
> Read more about the new feature here!

翻訳してもらった

> 未使用のキーを活用して、新しい Hyper Key 機能をお試しください。Caps Lock などの単一のキーを、⌃⌥⌘⇧ の 4 つの修飾キーの組み合わせである Hyper Key に変換できます。この追加修飾キーは、すべてのアプリでのキーボードショートカットを強化し、Raycast やその他のアプリケーションで生産性を向上させる軽量コンパニオンとして機能します。
> 
> Hyper Key をカスタマイズするには、設定 → 詳細 → Hyper Key に進んでください。
> 
> 新機能の詳細についてはこちらをご覧ください！

なるほど、わかるようなわからんような...

ちゃんと知りたかったら公式のマニュアルとマニュアルに載ってるYouTube見て下さい

https://manual.raycast.com/hyperkey

## 早速試す

とりあえず説明の通りに設定からHeyper Keyを探す

![CleanShot 2025-02-07 at 00.05.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565925/1e5eb622-e41a-b766-81c0-179cc14bdac8.png)

Heyper Keyに設定できる種類は結構豊富
（左右のControl, Shift, Optionとかも選べるとは思ってなかった）

![CleanShot 2025-02-07 at 00.07.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565925/d590465b-6263-a47f-b977-fb542df36d21.png)

せっかく(?)なのでCapsLockを選択

![CleanShot 2025-02-07 at 00.08.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565925/fac33ccd-a779-95c5-1a4a-f42a0d9ba6a7.png)

そのあとExtensions画面に移動して、好きな拡張機能に対してショートカットを、CapsLockキーと他のキーの組み合わせで設定する
今回はCleanShot XのToggle Desktop Iconsを✦ + T(実際にはCapsLock + T)で指定する(全然使ったことがない)

![CleanShot 2025-02-07 at 00.30.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565925/97ca6141-d5c7-ab3a-aa28-ac85a0a1ec38.png)


そして⇪ + Tを押下すると、こんな感じでデスクトップのアイコンがついたり消えたりする

![CleanShot 2025-02-07 at 00.33.48.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565925/45688623-4aaf-2dd6-79fd-462c329a255a.gif)

## 使ってみた感想

さすがRaycast、悪いものは出さない。（こちらに使える頭があるかは置いといて）

⌃⌥⇧⌘が✦に置き換わるということで、ショートカットが大量にある人は使いこなした方が良さそう。
でも私は⌥で事足りているので、しばらくは使わないかも...
今後ショートカットが爆増したらお世話になります。

![CleanShot 2025-02-07 at 00.35.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565925/4cc20807-5879-f993-2040-9db74c33ca07.png)

✦の選択肢は全部試してみたけど、
⇪は設定画面にある通りCapsLockとして使いたい時も使い分けられるのが便利(何より他のショートカットを汚さない)

Left,Rightで⇧や⌘を選べるのは便利だけど、普段の入力と混じるのでナシかな
(大文字の入力は左右の⇧使ってるし、⌘もショートカットで左右とも混同しながら使ってる)

残りは、⌃と⌥なのだけれど、私のMacBook Airは左側にしかないから、左右の使い分けに辿り着けませんでした...

⌃⌥⇧⌘をモリモリショートカットで使ってますとか、左右のキーでショートカットを分けたい方、
ショートカットが足りない方はぜひ使ってみてはいかがでしょうか。
【ざっくりと理解するWeb技術入門】ステートレスとステートフル

## はじめに

Web開発を学んでいると、「ステートフル」と「ステートレス」という言葉に出会うことがあると思います。  
でも、いきなり **「HTTPは基本的にステートレスだから～」** なんて言われてもピンとこないですよね？  

「そもそもステートって何？」「ステートレスとステートフルって何が違うの？」  
そんな疑問を **ざっくりと** 理解できるように
具体例を交えて解説していきます！  

前提知識として以下の記事を読むとより理解できます。

▼「Cookie」と「セッション」って？


▼「リクエスト」と「レスポンス」って？


## 1. そもそも「ステート」とは？

「ステート（state）」は **「状態」** を意味します。  
突然ですが、こんな場面を想像してみてください。

### **例①：メモ帳アプリ**
- メモ帳を開いて「買い物リスト」と書く  
- メモ帳を閉じる  
- もう一度開いたら、さっきの「買い物リスト」が残っている  

これは **「ステートを保持している」** 状態ですね。メモ帳が「買い物リスト」を記憶してくれているからです。

### **例②：銀行のATM**
- ATMにカードを入れて暗証番号を入力  
- 「残高確認」を押して、残高をチェック  
- 「引き出し」ボタンを押してお金を引き出す  

このとき、ATMは **「この人は認証済み」** という状態を保持し、引き出し操作を可能にしています。  
もし毎回認証が必要なら、かなり面倒ですよね。

このように、**システムやアプリが「状態」を持つかどうか** が、ステートフル・ステートレスの違いを生みます。

---

## 2. ステートフルとステートレスの違い

### **ステートフル（Stateful）とは？**
「ステート（状態）を持つ」システムのこと。  
リクエストごとに過去のやり取りを覚えており、継続的なやりとりができる。

#### **✅ ステートフルの具体例**
1. **ログイン後のWebサービス**
   - 例: AmazonやNetflix  
   - 一度ログインすれば、次のページに移動してもログイン状態が続く  

2. **オンラインゲーム**
   - 例: FPSゲーム、MMORPG  
   - プレイヤーのレベルや装備情報をサーバーが記憶している  

    3. **チャットアプリ（LINE・Slackなど）**
   - メッセージ履歴や未読状態を保持し、リアルタイムで更新される  

---

### **ステートレス（Stateless）とは？**
「ステート（状態）を持たない」システムのこと。  
リクエストごとに **「すべてが初めての通信」** のように扱われる。

#### **✅ ステートレスの具体例**
1. **普通のWebページのアクセス**
   - 例: Google検索  
   - 毎回「どんな人が検索したか」は気にせず、新しい検索結果を返す  
   （Googleアカウントにログインや、広告最適化とかは今は気にしないでください🙇）

2. **REST API**
   - 例: Twitter API（ツイート取得など）  
   - 毎回、独立したリクエストとして処理される  

3. **駅の券売機**
   - 切符を買うとき、「前の人の購入履歴」は関係ない  
   - 毎回、新規の利用者として扱われる  

---

## 3. **Webの世界でのステートフル vs ステートレス**

|  特徴  | ステートフル | ステートレス |
|---|---|---|
| **状態の保持** | する（記憶する） | しない（毎回リセット） |
| **リクエストごとの独立性** | 依存する（前のリクエストと関連あり） | 独立している（毎回新しい処理） |
| **例** | ログインセッション、チャットアプリ、オンラインゲーム | 検索エンジン、REST API、駅の券売機 |
| **メリット** | 連続性がある、ユーザー体験が良い | スケールしやすい、サーバー負荷が少ない |
| **デメリット** | サーバー側の管理が大変、負荷がかかる | 毎回同じ処理が必要、ユーザーの識別が難しい |

---

## 4. **どちらを使うべき？**

### **🟢 ステートフルが向いている場面**
- ユーザーのログイン状態を維持したい（例: ECサイト）
- 継続的なデータ管理が必要（例: ゲームのセーブデータ）
- リアルタイム更新が求められる（例: チャットアプリ）

### **🔵 ステートレスが向いている場面**
- 負荷を抑えてスケールしやすくしたい（例: 検索エンジン）
- ユーザーの状態を保持する必要がない（例: ログインのいらない画像配信サービス）

---

## 5. **まとめ**
- **ステートフル**：状態を保持する → ログインセッション、チャット、ゲーム
- **ステートレス**：状態を保持しない → 検索エンジン、REST API、駅の券売機

どちらにも適材適所があります。  
「このシステムのこの機能は、状態を保持するべきか？」を考えることで、より良い設計の第一歩になります。

---

## 6. **参考資料**
- 『プロになるためのWeb技術入門』
- MDN Web Docs（[https://developer.mozilla.org/](https://developer.mozilla.org/)）

---

### ここまで読んでいただきありがとうございました！🙌
Web開発の全体像を広く理解するうえで、「ステートフルとステートレス」は大事な概念です。  
実際のサービスを見ながら、
「これはどっちかな？」と考えてみも面白いのでぜひ！！
誰も教えてくれない今のAtari環境の使い方

# 概要
Atari Breakoutを用いて、PPOを実装しようとしたところ、かなり躓いたためメモっておきます。

# エラー文
```
Environment `BreakoutNoFrameskip` doesn't exist.
```
Breakoutがないよと言われてしまう。

# 解決法
```
import ale_py
gym.register_envs(ale_py)  # unnecessary but helpful for IDEs
```
ale_pyをimportする。aly_pyがない時はpip installする。
gym.register_envsはなくてもいいが、コード補完をしてくれるようになるそう。

これで、今まで通り
```
env = gym.make('ALE/Breakout-v5', render_mode="human")
```
というようにgymで環境を作ればよい。
詳しくはこちらを見てください。
https://github.com/Farama-Foundation/Arcade-Learning-Environment
【Rails】i18nで入力された値を表示する方法

I18n.tでは変数を使うことができます。

```yml:ja.yml
ja:
  errors:
    messages:
      exclusion: "に%{value}は指定できません。"
```

```rb
validates :name, exclusion: { in: %w(sample test) }
```

`name`に`sample`を指定すると以下のようなエラーメッセージとなります。

```text
名前にsampleは指定できません。
```
A列にある文字列をB列に置換する低需要エクセルマクロ

# 置換するマクロ
『置換項目』シートのA列にある文字列をB列に置換するだけのマクロ。
置換したいものは『対象』に記載する。
※特にテキストベースで書き出したりはしない。

```VBA:Replace.word
Sub test()

Application.DisplayAlerts = False

Dim num As Variant

  num = WorksheetFunction.CountA(Range("A1:A100"))

For i = 1 To num

Sheets("置換項目").Activate
befor = Cells(i, 1)
after = Cells(i, 2)

Sheets("対象").Activate
Cells.Replace What:=befor, Replacement:=after

Next i

Application.DisplayAlerts = True


End Sub
```

上記をVBAに突っ込んでマクロ有効ブックにするればうまくいくはず。
そんなものなくてもよくね？とか言わないで。
テキストベースの手順書を作成する会社だと用意しておくと何かと便利。
KLダイバージェンス最小化 = 対数尤度最大化を直感的に理解してみる

いま松尾研の深層生成モデル講座（https://weblab.t.u-tokyo.ac.jp/lecture/course-list/deep-generative-model/ ）を受けているのですが、KLダイバージェンス最小化 = 対数尤度最大化が同義であることを、やっと直感的に理解できたので、それを共有させていただきます！

## 直感的なイメージ
対数尤度最大化とKLダイバージェンス最小化は **「目標とする確率分布をどれだけ正確に再現できるか？」** という問題です。

#### サイコロで考える
- 誰かが作ったサイコロを観察して、**「このサイコロは公正（1/6ずつ）か、それとも偏っているのか？」** を知りたいとします。
- 10回投げた結果： 「6」が3回出た。
- ここで、**サイコロの6の出る確率θを推定したい。**

#### **どの確率がもっとも「それっぽい」か？**
- **ケース1：θ = 0.3（正しい確率）**  
  - もしこのサイコロが「6が30%の確率で出る」サイコロだったら、この結果（10回中3回）は普通にあり得る。
- **ケース2：θ = 0.5（誤った確率）**  
  - もしこのサイコロが「6が50%の確率で出る」サイコロだったら、10回投げて3回しか出ないのはかなり不自然。

**この直感を数式にしたのが「対数尤度」** であり、  
**「どれだけ不自然な確率か？」を測るのがKLダイバージェンス** です。

## KLダイバージェンスを直感的に
KLダイバージェンスは **「モデルがデータをどれだけ間違えて予測しているか」** を測るものです。

- 経験分布（≒真の分布）と生成モデルのKLダイバージェンスが**大きい**  
  → モデルの確率がデータとズレていて、データをうまく説明できていない。
- 経験分布（≒真の分布）と生成モデルのKLダイバージェンスが**小さい**（ゼロに近い）  
  → モデルの確率がデータの確率に近く、データをよく説明できている。

## 対数尤度を直感的に
対数尤度とは、「観測されたデータが、モデルの確率でどれだけ説明できるか？」を測るもの。

- **尤度** = 「モデルがこのデータを生成する確率」
- **対数尤度** = 「対数を取ったもの」 → 計算しやすくなる。

- **対数尤度が高い**  
  → モデルがデータをよく説明している。  
- **対数尤度が低い**  
  → モデルがデータを説明できていない。

つまり、**「データをよく説明する = KLダイバージェンスが小さい = 対数尤度が大きい」** という関係になる。

## まとめ
1. 対数尤度最大化は、「データを最もよく説明する確率を探す」
2. KLダイバージェンス最小化は、「モデルの予測をデータの分布に近づける」
3. どちらも「モデルを正しくする」ために、実は同じことをしている！
ハッシュ値の表示形式を理解する：エンディアンとバイトオーダー

## はじめに

ファイルの整合性チェックやデータの検証で使用されるハッシュ値。同じデータに対して計算したはずなのに、使用するライブラリやツールによって異なる表示形式になることがあります。この記事では、その理由と実装時の注意点について解説します。

## 基本概念の整理

まず、重要な用語について説明します。

### ハッシュ値とは

ハッシュ値は、任意の長さのデータから一定の長さの値を生成する方法です。主な用途は：

- データの整合性確認
- ファイルの改ざん検知
- データの同一性チェック

### 代表的なハッシュ関数

1. **CRC32（4バイト）**
   - 単純な巡回冗長検査
   - データ破損の検出用
   - 32ビット整数として扱われることが多い

2. **MD5（16バイト）**
   - バイト列として扱われる
   - 現代では暗号用途では非推奨
   - ファイル検証などで依然使用される

3. **SHA-1/SHA-256（20/32バイト）**
   - より安全な暗号学的ハッシュ関数
   - バイト列として扱われる
   - セキュリティが重要な場面で使用

## エンディアンとバイトオーダー

マルチバイトのデータを扱う際、バイトの並び順（バイトオーダー）が問題となります：

```python
# 32ビット整数 0x12345678 のメモリ上の表現
ビッグエンディアン:    12 34 56 78
リトルエンディアン:    78 56 34 12
```

この並び順の違いが、ハッシュ値の表示に影響を与えることがあります。

## 実装による表示の違い

### CRC32の例

後述しますがCRC32値の場合、扱い方によって表示が異なる場合があります：

```python
import zlib
import struct

data = b"Hello, World!"
crc = zlib.crc32(data) & 0xFFFFFFFF

# 整数値として16進数表示
print(f"Integer: {crc:08x}")  
# 出力: "ec4ac3d0"

# ビッグエンディアンのバイト列として表示
bytes_be = struct.pack('>I', crc)
print("Big-endian bytes: " + ''.join(f'{b:02x}' for b in bytes_be))  
# 出力: "ec4ac3d0"

# リトルエンディアンのバイト列として表示
bytes_le = struct.pack('<I', crc)
print("Little-endian bytes: " + ''.join(f'{b:02x}' for b in bytes_le))  
# 出力: "d0c34aec"
```

### より長いハッシュ値の場合

MD5やSHA-1など、より長いハッシュ値は通常バイト列として扱われます：

```python
import hashlib

data = b"Hello, World!"

# MD5の計算（16バイト）
md5_hash = hashlib.md5(data).digest()
print("MD5 bytes: " + ''.join(f'{b:02x}' for b in md5_hash))
# 出力: "65a8e27d8879283831b664bd8b7f0ad4"

# SHA-1の計算（20バイト）
sha1_hash = hashlib.sha1(data).digest()
print("SHA-1 bytes: " + ''.join(f'{b:02x}' for b in sha1_hash))
# 出力: "0a0a9f2a6772942557ab5355d76af442f8f65e01"
```

## ハッシュ関数の歴史と実装の変遷

### 1970年代：チェックサムの時代

1970年代初頭、データの整合性を確認する簡単な方法としてチェックサムが使われ始めました。その代表が **CRC（Cyclic Redundancy Check）** でした。

実は、この時代は現在のようにx86系のリトルエンディアンCPUが主流だったわけではありません：

- Motorola 68000シリーズ：ビッグエンディアン
- IBM System/360：ビッグエンディアン
- DEC PDP-11：リトルエンディアン
- Intel 8080：バイトマシン（エンディアン非該当）

CRCの実装には以下の特徴がありました：

- 32ビット整数として実装（CRC32）
- 高速な計算が可能
- ハードウェアでの実装が容易

CRC32を実行するとアーキテクチャに従ったハッシュ値が得られます。

### 1980年代後半：ネットワークの発展

インターネットの普及に伴い、異なるシステム間でのデータ交換が重要になってきました：

- ネットワークバイトオーダー（ビッグエンディアン）の標準化
- プロトコル間での一貫した表現の必要性
- クロスプラットフォーム対応の重要性

この時期、チェックサムの表示形式に関する問題が顕在化し始めます。

### 1990年代：暗号学的ハッシュ関数の登場

新しい要件に対応するため、より高度なハッシュ関数が開発されました：

1. **MD5（1991年）**
   - 128ビット（16バイト）のハッシュ値
   - バイト列として設計
   - RSA Data Security社による標準化

2. **SHA-1（1995年）**
   - 160ビット（20バイト）のハッシュ値
   - NIST（米国標準技術研究所）による標準化
   - ビッグエンディアンでの表現を採用

これらの新しいハッシュ関数は、最初からバイト列として設計され、表示形式も標準化されていました。

### 2000年代以降：標準化の進展

セキュリティ要件の高まりとともに、新しい標準が確立されていきました：

1. **SHA-2ファミリー（2001年）**
   - SHA-256, SHA-384, SHA-512
   - より強力なセキュリティ
   - 一貫したバイト表現の採用

2. **業界標準の確立**
   - RFC（Request for Comments）による仕様の明確化
   - クロスプラットフォーム互換性の重視
   - セキュリティ要件の標準化

## まとめ

1. 初期のチェックサム実装は、効率性を重視
2. ネットワークの発展により、標準化の重要性が増加
3. セキュリティ要件の高まりが、新しい実装方法を促進

現代でも用途に応じてCRC32は使われます。その際のエンディアンの違いについて、このような歴史があったことを知っておくと役に立つかもしれません。
Railsのstrong parametersでJSONを受け取る方法

## 発生した問題

Rails の API でネストした JSON を受け取る際、strong parameters の設定が原因で unpermitted parameters エラーが発生。フロントエンドから送信した JSON が正しくパースされず、DB へ保存できなかった。

## テーブル定義

JSON 型のカラムを持つテーブルの migration. MySQL.

```ruby
create_table :xxx do |t|
  t.json :xxx
  t.timestamps
end
```

## Controller の実装例（エラー発生時）

strong parameters の設定が原因でエラー発生。以下のコードでは、ネストした JSON 内のキーが許可されず unpermitted parameters エラーとなる。

```ruby
class XxxController < ApplicationController

  # create アクションなど

  private

  def xxx_params
    params.require(:xxx).permit(:a_json_type)
  end
end
```

## フロントエンドの送信例

axios を使い、ネストした JSON を送信。

```javascript
axios.post('/xxx', {
  xxx: {
    a_json_type: {
      b_inside: 1,
      c_inside: 2
    }
  }
}, {
  headers: {
    'Content-Type': 'application/json'
  }
})
```

## 解決策

strong parameters でネストしたオブジェクトを許可するため、キーをハッシュとして指定する必要あり。下記のコードに修正。

```ruby
class XxxController < ApplicationController

  # create アクションなど

  private

  def xxx_params
    params.require(:xxx).permit(a_json_type: {})
  end
end
```

この修正により、ネストした JSON 内のキーが正しく許可され、DB へ正常に値が保存可能。DB 側で JSON 型を利用することで、JSON のパース処理を自前で実装する手間が省ける。
Stripe サンプル「Checkout を使用した構築済みのサブスクリプション」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680230/909d4937-da6a-52ad-b99b-ddba0980521b.png)

# はじめに

カード決済系で [Stripe](https://stripe.com/jp) サービスを知りました。
まずは慣れるために Youtube で勉強です。

# Stripe とは？

Stripe（ストライプ）はオンライン決済サービスです。説明はいろいろなサイトがあるので省略。

# 開発環境

- OS : Windows 11 Pro
- Node : 20.16.0
- npm : 10.8.1
- Cursor(IDE) : 0.42.3

# サンプル作成

[Stripe Checkout を使用した構築済みのサブスクリプションページ](https://docs.stripe.com/billing/quickstart)

## パッケージ作成

```
> npm init -y
```

## Stripe アカウント作成

https://dashboard.stripe.com/login

- 公開可能キー：XXX1
- シークレットキー：XXX2

## package.json

```
{
  "name": "node_stripe_subscription",
  "version": "1.0.0",
  "main": "server.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "nodemon server.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "description": "",
  "dependencies": {
    "express": "latest",
    "nodemon": "latest",
    "stripe": "latest"
  }
}
```

## server.js

```
// express でローカルサーバーを起動
const express = require("express");
const app = express();
const PORT = 3000;

// This is your test secret API key.
const stripe = require("stripe")(
  "XXX2"
);

// ドメイン。成功時の戻り先
const YOUR_DOMAIN = "http://localhost:3000";

// 静的ページのディレクトリ　index.htmlがデフォルトで読み込まれる
app.use(express.static("public"));

// 「申し込みはこちら」ボタンの処理
app.post("/create-checkout-session", async (req, res) => {
  try {
    // 登録した商品のプライスリストを取得
    const prices = await stripe.prices.list();
    // console.log(prices);
    const session = await stripe.checkout.sessions.create({
      line_items: [
        {
          price: prices.data[0].id,
          quantity: 1,
        },
      ],
      mode: "subscription",
      success_url: `${YOUR_DOMAIN}/success.html?session_id={CHECKOUT_SESSION_ID}`,
      cancel_url: `${YOUR_DOMAIN}/cancel.html`,
    });
    // HTTPステータス303で、リダイレクト
    res.redirect(303, session.url);
  } catch (err) {
    console.log("[ERROR] " + err);
  }
});

app.listen(PORT, console.log("サーバー起動！"));

```

### Stripe API

- [stripe.prices.list](https://docs.stripe.com/api/prices/list)
- [stripe.checkout.sessions.create](https://docs.stripe.com/api/checkout/sessions/create)

# おわりに

今回は単純なサブスクリプション（継続支払い）の登録だけだったので、とても簡単に作成することができました。
実際には [Webhookイベント](https://docs.stripe.com/payments/handling-payment-events) をいろいろと処理するみたいなので、もっと複雑になると思われます。

作成した `Stripe アカウント`を削除したいんですが、アカウント削除にたどり着けない。。。

---

**参考（感謝）**　

- [Node.jsとStripeAPIで決済システムを構築してみよう ~サブスク導入編~](https://www.youtube.com/watch?v=gGkqFefpkVI)
- [GitHub](https://github.com/mt-magic/node_stripe_subscription)
- [Stripe DOCS](https://docs.stripe.com)
- [Stripe DOCS 開発者向け](https://docs.stripe.com/development)
（前提情報） 筆者の自己紹介

# 本記事について
地方（高知市）に移住に関する内容をまとめる前に、筆者のバックグラウンドをまとめさせていただきます。

# 筆者の基本情報
筆者は 大阪で生まれ育ち、大学卒業後、2009年から 大阪で社会人生活をスタートしました。
エンジニアではない仕事からキャリアをスタートし、インフラエンジニア 、 情シス部門 などを経由して、 地方（高知市）へ移住いたしました。
地方へ移住された方は、Web系（フロントエンジニア） や ソフトウェア開発に関する経験をお持ちの方が多いと思います。当方はこれらの経験がありません。
ですが、現在は 高知県高知市 に移住し、完全フルリモートで インフラエンジニア として業務に従事しております。


# 職務経歴
エンジニア職による新卒採用でしたが、キャリアのスタートは外的要因により エンジニア職 ではありませんでした。
ただ、自主的な学習や活動によりエンジニア部門へ異動し、複数回の部署異動 や 様々な業務担当の変化により、多種の業務経験を積みました。
ですが、 開発エンジニア に関する業務経験を積む機会はありませんでした。
 - 【大阪時代】非IT系のコールセンター業務（管理者）
 - 【大阪時代】インフラ全般管理部門（縦割り組織）の ハウジング業務担当 （部門間調整が中心）
 - 【大阪時代】インフラ全般管理部門（縦割り組織）の Windowsサーバ構築・運用
 - 【大阪時代】セールスサポートエンジニア （メンバー）
 - 【大阪時代】非IT企業の情報システム部門（運用管理課 ⇒ 企画課）
 - 【高知移住後】クラウドソリューション事業のインフラエンジニアとして業務に従事（現職）

# 筆者の技術力/経験値（大阪時代）
### インフラ関連
 - Windowsサーバの構築・運用
 - ネットワーク関連の基礎知識（CCNP レベル）
 - AWSにおけるサーバ構築・運用（非IT企業）
 - AWSに関する資格取得（AWS Certified Solutions Architect - Professional / 独学取得） など

### アプリケーション関連
 - *実務経験なし*
 - 簡単なコードの実装（入門書レベル（Python））

### ソフトスキル
 - 非IT企業へのパッケージソフトウェアの導入と運用整備（運用標準化と安定化）
 - 社内調整（部門間調整 / 社内システム導入の企画・遂行・運用 など）
 - 社内情シス業務の全般（端末キッティング、メンバー教育 など）


# 地方（高知市）移住について
具体的な活動は、次記事以降でまとめますが、概要としては以下の通りです。

|トピック | 内容 |
|:-|:-|
|移住した時期|2019年（コロナ禍 前）|
|移住先  |  高知県高知市（地方の中でも都会） |
|高知県への移住を検討するに至ったきっかけ|妻の希望（地元愛）|
|移住を決断した理由|家庭事情|
|移住に向けた活動期間|3年 （本格的な活動は 9か月）|

# 次以降の記事について
次以降の記事では、 移住前（大阪時代） ⇒ 移住後（高知移住後） ⇒ 移住を経験して感じたポイントなど の順にまとめていきます。
例えば、以下のような内容を記載させていただく想定です。
- 移住に向けて習得しておくべきスキル や 考え方 （ 文章力 / 推測・傾聴力 / タスクの分解力 など ）
- 地方の職を探すことの難しさ。（ 県の就職支援を使う / SNS などでの情報収集 など ）
- 実際に移住するとなった場合の 退職・転職 時期、住居探し などの注意事項
- 移住前にやっておいた方が良いアプローチ（ 事前に収集しておくべき情報 / 現地（地方）のイベント参加 など ）
- 移住後の生活の変化（ フルリモートでの仕事について / "ワーケーション" など ）
【目次】 地方（高知県高知市）へ移住したインフラエンジニアの記録 （順次更新予定）

# 本ブログについて

2019年8月に、生まれ育った大阪から 妻の地元である高知県（高知市）に移住しました。
現在は、自宅から完全フルリモートで インフラエンジニア として業務に従事しております。

高知県へ移住するにあたり、私の強み（職務経験）である【情シス・インフラ の経験・知識を活かせる職がないのでは】と非常に悩みました。
同じように 「地方に移住したい」、「地元に帰りたい」と悩みつつ思いを募らせている方もいらっしゃると思います。

どこまで参考になるかわかりませんが、私と似たような悩みを持つ方の参考になればと思い、ブログを書かせていただきます。


# 目次
以下のような内容で順次ブログを書かせていただきます。（変更の可能性あり）

〇 [（前提情報） 筆者の自己紹介](https://qiita.com/sumiyama_embomajp/items/2dc0176cde136f9d7c99)
〇 [（移住前 : 大阪編） 移住に向けた活動の開始（移住に対する不安の言語化）](https://qiita.com/sumiyama_embomajp/items/c6252461a351807d74c6)
〇 [（移住前 : 大阪編） 地方移住のための活動 - 情報収集・就職活動](https://qiita.com/sumiyama_embomajp/items/ad7d25ab405927551a45)
〇 （移住前 : 大阪編） 実際に移住する際に発生した問題点
〇 （移住後 : 高知編） 地方へ移住した後の生活
〇 （移住後 : 高知編） 移住前のイメージとの違い
〇 （移住後 : 高知編） 地方でエンジニアとして生きていくために必要なスキルと行動
〇 （移住に関する情報共有） 移住後に感じた 移住前 に実施すべき行動について
〇 （移住に関する情報共有） 移住を考えておられる方へのアドバイス
docker x MinIO 環境構築

## 概要

**MinIO で `sample-bucket` バケットが存在しない場合に自動作成する仕組み** を実装した。  
当初、MinIO 起動直後に初期化用の `mc` コマンドを実行すると `connection refused` エラーが発生していたが、**ヘルスチェック** と **depends_on の condition: service_healthy** を活用することで解決した。

## Docker Compose の構成

以下が最終的な `docker-compose.yml` の内容である。

```yaml
version: '3.8'
services:
  minio:
    image: minio/minio:latest
    container_name: minio
    ports:
      - "9000:9000"
      - "9001:9001"
    environment:
      MINIO_ROOT_USER: minio
      MINIO_ROOT_PASSWORD: minio123
    command: server /data --console-address ":9001"
    # ヘルスチェックの設定 (例)
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/ready"]
      interval: 5s
      timeout: 2s
      retries: 5
    restart: unless-stopped

  minio-init:
    image: minio/mc
    depends_on:
      # minio が "healthy" になるまで minio-init の起動を待機
      minio:
        condition: service_healthy
    entrypoint: /bin/sh
    command: >
      -c "
      mc config host add local http://minio:9000 minio minio123 &&
      if mc ls local/sample-bucket; then
        echo 'Bucket sample-bucket already exists.'
      else
        echo 'Bucket sample-bucket not found. Creating...'
        mc mb local/sample-bucket
      fi
      "

volumes:
  minio-data:
```

## ポイント解説

### 1. MinIO のヘルスチェック設定

MinIO コンテナに以下のヘルスチェック設定を追加することで、コンテナが本当にリクエストを受け付け可能な状態になっているかどうかを判定している。

```yaml
healthcheck:
  test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/ready"]
  interval: 5s
  timeout: 2s
  retries: 5
```

この設定により、MinIO が起動してからヘルスチェックで OK と判断されるまで、依存関係のあるサービス（今回の場合は `minio-init`）は実行を待機することができる。

### 2. minio-init サービスでのバケット自動作成

`minio-init` サービスでは、MinIO Client (`mc`) を用いて、以下の手順でバケットの存在確認と作成を行っている。

- **ホストの登録:**  
  `mc config host add local http://minio:9000 minio minio123`  
  これにより、`local` というエイリアスで MinIO サーバーに接続できるように設定する。

- **バケットの存在確認と作成:**  
  ```bash
  if mc ls local/sample-bucket; then
    echo 'Bucket sample-bucket already exists.'
  else
    echo 'Bucket sample-bucket not found. Creating...'
    mc mb local/sample-bucket
  fi
  ```
  ここで、既に `sample-bucket` バケットが存在する場合はその旨を表示し、存在しなければ `mc mb` コマンドで新規作成するように設定している。

### 3. depends_on と condition: service_healthy の活用

`minio-init` サービスは、`depends_on` において以下のように設定している。

```yaml
depends_on:
  minio:
    condition: service_healthy
```

これにより、MinIO コンテナのヘルスチェックが成功（healthy 状態）するまで `minio-init` は起動しないため、MinIO が完全に起動しないうちに接続しようとして `connection refused` エラーが発生することを防いでいる。

## まとめ

今回の実装では、Docker Compose の **ヘルスチェック** 機能と `depends_on: condition: service_healthy` を活用することで、MinIO の起動タイミングを適切に待機し、初期化スクリプトが正常に実行できるようにした。
本当は、アクセスポリシーをパブリックに設定したかったが、うまくいかず、その部分は手動で行うことにした。今後解決できたらこうしんしようとおも
【Windows】nmakeのパスを通す

nmake単体で調べても、なかなか情報が出てこなかったので、ここにメモしておく。

# 環境
* Windows 11
* Visual Studio 2022

# 問題
とあるSDKとサンプルプログラムをcmakeでビルドしようとしたところ、nmakeが見つからないと怒られた。

# 解決方法

https://visualstudio.microsoft.com/ja/visual-cpp-build-tools/

上のリンクから、ビルドツールのインストーラをダウンロードして起動してインストールします。

次のパスを、手動で通します。（バージョンは各自置き換えてください）
```
C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\xx.xx.xxxx\bin\Hostx64\x64
```

# おわりに
Windowsが大嫌いなのですが、環境構築はCopilotのおかげで少し楽になりました。
しかし、やっぱりUNIX系OSと比べると環境構築のコストは雲泥の差ですね。
GitHub　CLI メモ

##  GitHubをCLIで使う時のメモ
今回は私がGitHubのCLIに慣れていきたいと思うので書きました。

### 最新にする
```bash
git pull
```
### 変更の確認
```bash
git fetch
```

### 作業中のブランチを最新にする
#### mainブランチに行く
```bash
git checkout main
```
最新状態にする
```bash
git fetch
git pull
```
#### 作業中のブランチに戻る
```bash
git checkout test #testというブランチ名に移動する
```
#### 最新状態を適応
```bash
git merge origin
```

### 接続されているリモートリポジトリを確認する
```bash
git remote -v
```

### 接続されているリモートリポジトリを変更する
```bash
git remote set-url origin #新しいURL　SSHで指定する
```


### 接続されているリモートリポジトリとの連携を消す(デフォルトは`origin`だがリポジトリ名の時もある)
```bash
git remote remove origin
```