OmniAICreator/Qiita-1.07M huggingface dataset:
3分わかるでAPIデザインについて

# はじめに

APIの基本から、デザインしていくことの重要性までをサクッと説明していきます。
AWS SUMMIT 2024のステージで紹介されていた内容を参考にしています。
早速解説します！

# 対象読者

- APIについて知りたい方
- APIデザインについて興味のある方
- API使ったことがある方

# 目次

1. APIとは
2. APIデザインの重要性
3. 良いAPIデザインとは
4. APIデザインで他に考慮するべきポイント

# 1. APIとは

APIについて簡単に説明します。
API（Application Programming Interface）は、

**アプリケーション同士が情報をやり取りするためのルールやツール**

のことを指します。
例えば、、

天気予報アプリが気象データを取得するために気象APIを利用するようなケースなどがあります！


:::note info
まとまったデータや機能を簡単に使わせていただくことができます！
:::

# 2. APIデザインの重要性

API開発で課題となるものをPostmanが公開しています。
以下の図からわかるように、最も大きな課題は「人手と時間の不足」ですが、その次に挙げられるのが **「APIデザインスキルの不足」** です。
つまり、<font color="Red">**APIデザインスキルを身につけると需要のあるエンジニアになれる**</font>ということです！

![スクリーンショット 2024-07-12 17.32.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1991303/eb3f2e8e-3256-07e0-fe78-08c71a246244.png)
引用: https://www.postman.com/state-of-api/executing-on-apis/#obstacles-to-producing-apis-a-unique-challenge-for-big-companies

# 3. 良いAPIデザインとは

API設計する際に2つのパターンが想定されます。

1. コードやリソースからの設計
2. ユースケースの設計

どちらが良いアプローチでしょうか？

正解は②です！
**カスタマーのユースケースから逆算して設計を考えることが重要**です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1991303/d04a3bd4-e05c-1623-7075-cb6fc67ca42a.png)

では、具体的にどのように設計をすれば良いのでしょうか？

実際の例を見て比べると分かりやすいと思うので、ブログに「コメント」や「いいね」をできるアプリを例に考えてみます。
- パターン1: コードやリソースからの設計
- パターン2: ユースケースの設計

### パターン1: コードやリソースからの設計

Blog サービスの疑似コードを作成
```
class Posts {
   createComments() { ... }
   addLikes() { ... }
}
```

API作成
```
// ある投稿にコメントをしたい
POST /posts/{post_id}
{"type": "comment", "data": ...}

// ある投稿にLikeをしたい 
POST  /posts/{post_id}
{"type": "likes", "data": ...}
```

### パターン2: ユースケースの設計

APIを設計
```
// ある投稿にコメントをしたい
POST /posts/{post_id}/comments

// ある投稿にLikeをしたい 
POST /posts/{post_id}/likes
```

Blog サービスの疑似コードを作成
```
createCommentOnPost(postId) { ... } likePost(postId) { ... }
```

# 4. APIデザインで他に考慮するべきポイント

考えるポイントの一部を箇条書きで整理しました。

- わかりやすいドキュメンテーション
- API スタンダード
    - 標準仕様への準拠
    - スタイルガイド等 
- 持続可能性
    - 下位互換性
    - バージョニング
- 非機能要件
    - セキュリティ
    - 性能, 拡張性

# おわりに

APIの基本、重要性、設計パターンについて解説しました！
APIデザインを考えるきっかけになれば嬉しいです！
WSL2でgazebo（旧ignition）を起動すると、強制終了するときの解決方法

お疲れ様です。秋並です。

WSL2でgazebo（旧ignition）を起動すると、強制終了してしまうことがあったのですが、以下の環境変数を設定したら改善したので記載しておきます。

```
export LIBGL_ALWAYS_SOFTWARE=1
```

<br>

上記を設定した後で、gazeboを起動すれば強制終了せずに起動します。

```
ign gazebo
```

# 参考サイト
- [OGRE2: Gazebo (Fortress) rendering with OGRE2 crashes in a WSL2 environment with a dedicated GPU present, aka WSLg #662](https://github.com/gazebosim/gz-rendering/issues/662)
マイグレーション実行時のメモリ不足エラー

# はじめに
実務で遭遇したので今後の備忘録として書きます。


# バージョン

- PHP: 8.2
- Laravel: 11
- MySQL: 8.3


# 経緯

DBマイグレーションを実行したときに下記エラーが発生しました。

``` console
$ php artisan migrate
PHP Fatal error:  Allowed memory size of 8388608 bytes exhausted (tried to allocate 12288 bytes) in ...
```


# 原因と対策

調べてみると、phpのメモリ制限をオーバーしかけたとのことでした。
php.ini内の<b>memory_limit</b>の値(デフォルトは128M)を変更することで解決できます。

``` php.ini
memory_limit=128M → -1(無制限)に変更
```

``` console
$ php -i | grep memory_limit
memory_limit => -1 => -1
```

[memory_limitについて](https://www.php.net/manual/ja/ini.core.php#ini.sect.resource-limits)

また今回のようにマイグレーション実行時だけメモリ容量を上げたい場合は下記のコマンドを実行すると良いです。

``` console
$ php -d "memory_limit=-1" artisan migrate
```
[dオプションについて](https://www.php.net/manual/ja/features.commandline.options.php)
C_TS4FI_2021 SAP Certified Associate - SAP S/4HANA 2021 for Financial Accounting対策（13/100）

【13日目】
トピック 1：組織割当およびプロセス統合（13/15）

≪問題13≫
SAP S/4 HANAシステムで、どの会社コードでも使用されていなくなった業務のG/L勘定をアーカイブする必要があります。
G/L勘定のすべてのデータをアーカイブするための前提条件は、次のうちどれですか？
正しい答えを3つ選択してください。
□勘定が自動勘定設定で設定されない。
□勘定に取引金額が存在しない。
□G/L勘定の会社コードデータに削除フラグを設定する。
□取引金額が、カスタマイズ可能な年数よりも古い。
□G/L勘定の勘定コード表に削除フラグを設定する。

≪解答≫
□勘定が自動勘定設定で設定されない。
■勘定に取引金額が存在しない。
■G/L勘定の会社コードデータに削除フラグを設定する。
□取引金額が、カスタマイズ可能な年数よりも古い。
■G/L勘定の勘定コード表に削除フラグを設定する。

≪解説≫
◆G/L勘定マスタをアーカイブする場合、その勘定に対する取引データを事前にアーカイブしておく必要がございます。
◆G/L勘定マスタをアーカイブするための条件は、以下の通りです。
（1）勘定コード表レベルのデータに対して：
    - 削除フラグ設定
    - 会社コード固有データなし
    - 依存原価要素なし
（2）会社コードレベルのデータに対して：
    - 削除フラグ設定
    - 取引金額なし
    - 転記済伝票（未消込明細、消込済明細ともに）なし
非同期処理でMongoDBに接続Expressサーバーを起動

非同期処理でMongoDBに接続し、Expressサーバーを起動する方法
以下に、非同期処理を用いてMongoDBに接続し、Expressサーバーを起動するコードの例を示します。

データベース接続関数
まず、connectDB.jsファイルを作成し、MongoDBに接続する関数を定義します。

```javascript

// connectDB.js
const mongoose = require('mongoose');

const connectDB = async (url) => {
  try {
    await mongoose.connect(url, {
      useNewUrlParser: true,
      useUnifiedTopology: true,
    });
    console.log('DB接続成功');
  } catch (error) {
    console.error('DB接続エラー:', error);
  }
};

module.exports = connectDB;
```
サーバー起動のためのコード
次に、app.jsファイルを作成し、データベース接続後にExpressサーバーを起動するコードを記述します。

```javascript
// app.js
const express = require('express');
const connectDB = require('./connectDB'); // データベース接続関数をインポート

const app = express();
const port = 8000;

// データベース接続URL
const dbUrl = 'ライフガード';

const startServer = async () => {
  try {
    // データベースに接続
    await connectDB(dbUrl);
    // サーバーを起動
    app.listen(port, () => {
      console.log(`サーバーがポート${port}で起動しました`);
    });
  } catch (error) {
    console.error('サーバー起動エラー:', error);
  }
};

// サーバー起動関数を呼び出す
startServer();
```
### 非同期関数の定義:
asyncキーワードを使って非同期関数startServerを定義
### データベース接続:

awaitキーワードを使って、非同期関数connectDBの完了を待ちます。
connectDB関数はMongoDBに接続し、接続成功または失敗のメッセージをコンソールに出力します。
### サーバーの起動:

データベース接続が成功した後で、Expressサーバーを指定したポートで起動します。
サーバーが正常に起動すると、"サーバーがポート8000で起動しました"というメッセージがコンソールに表示されます。
### エラーハンドリング:

try-catchブロックを使って、データベース接続やサーバー起動時のエラーをキャッチし、コンソールにエラーメッセージを表示します。
『コードモンスター大図鑑 プログラミングでゲットだぜ！』「【PR】コドモンレポートキャンペーン」

# 『コードモンスター大図鑑 プログラミングでゲットだぜ！』
**Qiita初投稿**です。

本記事は私が日々プログラミングを勉強しているpaizaがリリースした
    『コードモンスター大図鑑 プログラミングでゲットだぜ！』
のプレイレポートとなります。

[ゲームへのリンク（https://paiza.jp/entry/code_monster_ub）](https://paiza.jp/entry/code_monster_ub)

## １　コドモンを集めよ
paizaの特典でもらったコインとダイヤを消費して、ガチャを回して集めたのが下記のコドモン。

:::note info
LEADER１枚及びPARTY５枚のコドモンを設定できる。
:::



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831870/ac16e6d2-7a6f-970c-1917-e1566510028d.png)
  
## ２　ガチャをしよう
コインとダイヤを使用してガチャができる。
今回はデジタルコドモンガチャをやってみることにする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831870/083199c0-3b61-d56c-c984-efed56676ecd.png)

:::note warn
おっとコインが足りなかった。
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831870/aef36df3-4c11-76bf-165b-b81c8726ca1b.png)

## ３　冒険に行こう
C#しか勉強していないので、C#を選んで冒険（問題を解く）に行く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831870/b9a26b5d-66ee-06ba-e878-0cceae432828.png)
下記のような問題を解いていく。今回は４問解答した。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831870/e679221b-a6e0-35d4-1250-83e0a3cbd006.png)
クエストクリア。コインを70枚とダイヤを３個ＧＥＴした。
クエストを進行すると次のクエストでは、問題の難易度が少しずつあがっている感覚がある。プログラミング初心者にはとっつきやすい内容となっていると思う。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831870/9cdd9836-2177-9e68-21f5-cc1e62a753ec.png)

## ４　コインが足りないので、コドモンとお別れしよう
なんと、お別れするとコインがもらえるのだ。
ガチャをして、同じカードが何枚もあれば、１枚残してお別れしてコインを稼ぎガチャをたくさん回してコドモンコンプリートを目指そう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831870/8536db61-0983-18b3-1716-da915d59f7fe.png)

## ５　ガチャは君たち自身で実際にやってみよう
結局、先ほどのコドモンは１枚しかなかったため、お別れはしなかった。結果ガチャを回すことはなかった。プログラミング初心者でもとっつきやすい内容であるため、このゲームをお勧めする。

## ６　後がき
私はpaizaラーニングのレベルアップ問題集をやっているが、頭を使う問題が多いため、解くことが億劫になる時がある。そういう時に、プログラミング拒絶反応を緩めるため、今回のゲームで簡単な問題を解くようにしている。
放送延長する番組の条件を探して試行錯誤するつまらん記事

TS抜きでの録画が野球中継延長で失敗したー
同じくオリンピック中継で失敗したー
こんな悲劇を緩和するために、放送時間が変わる番組はなくしていきたい(いや、なくす必要はないんだが延長してかき回す迷惑行為をするくらいなら正直消えてほしい)し、影響を受ける可能性があるとわかっていれば時間を長めにする等の対策もできる。
(mirakurunやepgstationも市販の録画機同様EPG取得し変更に対応できるのではあるんだが、例のspyfamiliy事件よろしく必ず対応できるわけではありませんしね。)

条件を少しずつ探っていきたい、地道に更新していきたいと思う。

NHK総合の場合

延長しない(というかスポーツ中継ではない)
ジャンル：ニュース・報道を含む　ニュースにも3番目が多いがスポーツジャンルは含まれていることが多い。
ジャンル：スポーツでスポーツニュースを含む　スポーツニュースを含む中継はありえないはず。
ジャンル：相撲・格闘技 を含む　時間は早朝(深夜)、当然中継なわけはない。
ジャンル：音楽 を含む
ジャンル：ドキュメンタリー・教養 を含む
放送の長さが1時間未満：どう見ても中継ではない。通常120分以上でしょうが、サブチャンネルとかNHKG,E,BS行き来とかだと1時間ちょっとの枠になるケースもあるみたいだ。
タイトル：みんなの体操　健康番組である。
説明文：「まで行われた」を含む。録画か何かでしょう。
タイトル：「ハイライト」を含む。中継っちゃ中継と言えなくもないですが、録画なので時間通りです。

おそらく延長しない
タイトル：「ウィンブルドン」(テニス。ジャンルにテニスはなかったはず)
タイトル：「ストーリーズ」　ドキュメント的な番組の可能性が高い
ジャンル：マリン・ウィンタースポーツ を含む　延長の事例は見たことがない

可能性は低いが少し延長する可能性がある
ジャンル：(1番目)相撲・格闘技 を含む(相撲)　タイトル：大相撲　時間は夕方で終了予定は18時。録画に響くレベルは土曜日曜(14,15日目)くらいと思われる。19時のニュース以降を変更する可能性はほぼないはずなので直近18時くらいからの番組だけ考慮すればよい。

延長するかどうかはわからないが中継の可能性が高い
説明文：「で放送継続」を含む
ジャンル：サッカー、説明文：「【解説】」を含む
タイトル：「高等学校野球選手権」を含む。まぁ甲子園のことですな。

判別する際に、ブラックリスト方式かホワイトリスト方式かで悩みますね。あとできるだけ単純な処理にしたい。...というか延長の可能性があるものについては表記を義務付けろよ余計な仕事させんじゃねぇ放送局どもめ。
CoreMP135でタッチパネルにタッチした結果を取得する

## 目的
M5StackのCoreMP135にて、タッチパネルにタッチした結果を取得します。

### 1. デバイスファイル:
Linuxでは、タッチパネルは/dev/input/event0やevent1などのファイルにマッピングされています。以下のコマンドで、デバイスファイルを特定します。
CoreMP135でコマンドを実行し、/dev/input/event0にマッピングされていることが確認できました。

```bash
 $ cat /proc/bus/input/devices
I: Bus=0018 Vendor=0000 Product=0000 Version=0000
N: Name="EP0110M09"
P: Phys=
S: Sysfs=/devices/platform/soc/4c004000.i2c/i2c-0/0-0038/input/input0
U: Uniq=
H: Handlers=event0
B: PROP=2
B: EV=b
B: KEY=400 0 0 0 0 0 0 0 0 0 0
B: ABS=2608000 3
```

### 2. デバイスファイルのオープン:
特定したデバイスファイルをオープンします。
C++では、以下のようになります。

```cpp
int fd = open("/dev/input/event0", O_RDONLY);
if (fd == -1) {
    perror("Error opening device");
    exit(EXIT_FAILURE);
}
```

input_event構造体からタッチパネルの状態を取得します。input_event構造体は、Linuxのイベント入力するシステムで、ユーザースペースにイベント情報を伝達するために使用されます。

```c
#include <linux/input.h>

struct input_event {
    struct timeval time;  // イベントのタイムスタンプ
    __u16 type;           // イベントタイプ
    __u16 code;           // イベントコード
    __s32 value;          // イベント値
};

struct timeval time:
   - イベントが発生した時刻を表すタイムスタンプです。
   - 秒とマイクロ秒の精度で時間を記録します。

__u16 type:
   - イベントの種類を示す16ビットの符号なし整数です。
   - 主な種類には以下があります：
     - EV_KEY: キーやボタンのイベント
     - EV_REL: 相対座標の変化（例：マウスの移動）
     - EV_ABS: 絶対座標の変化（例：タッチスクリーンの位置）
     - EV_SYN: 同期イベント

__u16 code:
   - イベントの具体的な内容を示す16ビットの符号なし整数です。
   - typeに応じて意味が変わります。例えば：
     - EV_KEY の場合：KEY_A, BTN_LEFT など
     - EV_ABS の場合：ABS_X, ABS_Y, ABS_PRESSURE など

__s32 value:
   - イベントの値を表す32ビットの符号付き整数です。
   - codeに応じて意味が変わります。例えば：
     - EV_KEY の場合：0（離す）、1（押す）、2（長押し）
     - EV_ABS の場合：絶対座標の値
```

タッチスクリーンのイベントの場合は、
   - type: EV_ABS
   - code: ABS_X（X座標）またはABS_Y（Y座標）
   - value: 座標の値（ピクセル単位など）
という情報を得ることができます。


### 3. イベントの読み取り:
input_event構造体を使用してイベントを読み取ります。

このコードは、/dev/input/event0からタッチパネルイベントを読み取り、X座標、Y座標、圧力、タッチの状態（プッシュ/リリース）を出力します。


```c
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/input.h>

#define DEVICE_PATH "/dev/input/event0"

int main() {
    struct input_event ev;
    int fd = open(DEVICE_PATH, O_RDONLY);
    if (fd == -1) {
        perror("Error opening device");
        return EXIT_FAILURE;
    }

    while (1) {
        ssize_t n = read(fd, &ev, sizeof(struct input_event));
        if (n == (ssize_t)-1) {
            perror("Error reading event");
            break;
        }

        if (n != sizeof(struct input_event)) {
            fprintf(stderr, "Error: incorrect read size\n");
            break;
        }

        if (ev.type == EV_ABS) {
            switch (ev.code) {
                case ABS_X:
                    printf("X: %d\n", ev.value);
                    break;
                case ABS_Y:
                    printf("Y: %d\n", ev.value);
                    break;
                case ABS_PRESSURE:
                    printf("Pressure: %d\n", ev.value);
                    break;
            }
        } else if (ev.type == EV_KEY && ev.code == BTN_TOUCH) {
            printf("Touch: %s\n", ev.value ? "Down" : "Up");
        }
    }

    close(fd);
    return EXIT_SUCCESS;
}

```

### 注意点:
- デバイスファイルへのアクセス権限が必要です（通常はroot権限が必要）


## 参考


https://github.com/nnn112358/CoreMP135_LovyanGFX_test/
Lambda に登録したKMSで暗号化した環境変数をLambdaで扱う方法

Lambda では API トークンなどを環境変数として登録できます。
さらに、KMSを使用して暗号化することで、よりセキュアにAPIトークンなどを保存することができます。

しかし、KMSを使用して暗号化した環境変数を扱う際に沼にハマったので記録を残しておきます。
(意外とこれに該当する記事がぱっと見つかりませんでした。。。)

## 結論: 暗号化するコード(Python)
```
def decode_variables(encrypted_token_name: str) -> Optional[str]:
    """
    Decrypts the encrypted value of an environment variable.

    Args:
        encrypted_token_name (str): The name of the environment variable containing the encrypted value.

    Returns:
        Optional[str]: The decrypted value. Returns None if decryption fails.
    """
    encrypted_token = os.environ.get(encrypted_token_name)
    if not encrypted_token:
        raise ValueError(f"{encrypted_token_name} environment variable is required.")

    kms_client = boto3.client('kms')
    try:
        decoded_token = base64.b64decode(encrypted_token)
        decrypted_token = kms_client.decrypt(
            CiphertextBlob=decoded_token,
            EncryptionContext={'LambdaFunctionName': os.environ['AWS_LAMBDA_FUNCTION_NAME']}
        )['Plaintext'].decode('utf-8')
        return decrypted_token
    except Exception as e:
        print(f"Error decrypting token: {e}")
        return None
```

## ハマったポイント
下記 kms クライアントで decrypt する際に、EncryptionContextを登録する必要があることがわからず沼にハマっていました。。。

```
kms_client.decrypt(
            CiphertextBlob=decord_token,
            EncryptionContext={'LambdaFunctionName': os.environ['AWS_LAMBDA_FUNCTION_NAME']}
)['Plaintext'].decode('utf-8')
```

特に下記のドキュメントを見ても、特に必須との記載はなく、必要のないものだと思っていましたが、これがないとエラーになっていました。。。
(強く推奨するとの記載があったので、必須と認識して良さそうです)

- Boto3 - decrypt
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/kms/client/decrypt.html
```
EncryptionContext (dict) –

Specifies the encryption context to use when decrypting the data. An encryption context is valid only for cryptographic operations with a symmetric encryption KMS key. The standard asymmetric encryption algorithms and HMAC algorithms that KMS uses do not support an encryption context.

An encryption context is a collection of non-secret key-value pairs that represent additional authenticated data. When you use an encryption context to encrypt data, you must specify the same (an exact case-sensitive match) encryption context to decrypt the data. An encryption context is supported only on operations with symmetric encryption KMS keys. On operations with symmetric encryption KMS keys, an encryption context is optional, but it is strongly recommended.

For more information, see Encryption context in the Key Management Service Developer Guide.

(string) –

(string) –
```
【CSS】ブラウザ幅ごとにスタイルを分けたい

# はじめに
今回はブラウザ幅ごとにスタイルを分けたい時の記述についてご紹介しようと思います。

# やり方

まずは幅の定義をします
``` width.scss
// 幅750px以下でスタイルをあてたい場合
@mixin sp {
  @media screen and (max-width: 750px) {
    @content;
  }
}

// 600px以上、800px以下でスタイルをあてたい場合
@mixin medium {
  @media screen and (600px <= width < 800px) {
    @content;
  }
}

```

定義し終わったら、使いたいscssファイルにimportします。
``` sample.scss
@use 'import/width' as g;

.container {
  // 通常のフォントサイズ
  font-size: 20px;

  // 幅750px以下でフォントサイズが40px
  @include g.sp {
    font-size: 40px;
  }

  // 幅600px以上、800px以下でフォントサイズが30px
  @include g.medium {
    font-size: 30px;
  }
  
}

```

# おわりに

いかがだったでしょうか。
今はレスポンシブデザインが主流ですのでぜひ使ってみてください！
【Xcode】これだけは覚えておけSwift Package Manager

# はじめに
iOSアプリ開発における依存関係管理ツールとして、「Swift package Manager」についての記事となります。

似たような依存関係管理ツールとしては、「Carthage」や「Cocoa Pods」などが有名かと思いますが、Xcode標準のツールとなる「Swift package Manager」の方が導入しやすいです。
あとは、使用したいパッケージが「Swift package Manager」に含まれているかどうかですね。。

また、調べると色々古い記事ばかりで最新のXcode環境では微妙に異なります。
とはいえ、基本的に導入手順は変わっていないので問題無いとは思いますが、最新のXcodeでの導入手順について記載していきます。

今回は、FirebaseのパッケージをSwift Pachage Managerで導入していこうと思います。

参考：　FirebaseをSwift Package Managerでインストールする方法
　https://firebase.google.com/docs/ios/swift-package-manager?hl=ja

Github
　https://github.com/swiftlang/swift-package-manager
 
↑ちなみに、なんならFirebaseの公式の導入手順も最新のXcodeでは無い模様

使用する環境は以下の通り
・Mac OS Sonoma 14.5
・Xcode 15.4
・使用言語 Swift (バージョンは5)

# 導入手順
### １）「File」＞「Add Package Dependencies」を選択
![スクリーンショット 2024-07-13 20.27.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3782130/03d01c6f-d24c-0ae6-0fd6-cdf99c5e15f1.png)

### ２）Swift Package Managerで使用したいパッケージを選択することが可能
Apple標準のパッケージがずらっと並んでいるが、
![スクリーンショット 2024-07-13 20.27.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3782130/b3dad6de-8f4a-25b2-4eaf-a732d50d7f79.png)

リポジトリのURLを直接入力することでも指定可能。
以下はFirebaseのリポジトリのURLを入力したときのScreenShot.
![スクリーンショット 2024-07-13 20.27.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3782130/a9373cda-717c-416f-fe7a-dcc0f078e353.png)

### ３） Dependency Ruleの指定
![スクリーンショット 2024-07-13 20.28.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3782130/d0f38678-73f7-54f6-e24d-c39fbe6e7e01.png)

記載されている通りではあるのだが、選択肢は以下の通り
| 選択肢 | 内容 |
|:-:|:-:|
| Up to Next Major Version  | 次のメジャーバージョンまで更新可能　例：10.29.0 < 11.0.0  |
| Up to Next Minor Version  | 次のマイナーバージョンまで更新可能　例：10.29.0 < 10.30.0  |
| Exact Version  | 固定のバージョン  |
| Range of Versions  | 手入力でアップデートのバージョン指定可能  |
| Branch  | ブランチを指定することも可能  |
| Commit  | コミット番号を指定することも可能  |

ちなみに、非常に分かりづらいが
パッケージ導入後にDependency Ruleを変更したい場合は
　PROJECT > Dependency Ruleタブ　で変更可能
![スクリーンショット 2024-07-13 20.40.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3782130/1e94ecf4-f618-072a-8dcb-cc639f4be776.png)

上記より、メジャーバージョンを更新する為には、Exact Version以降の選択肢が必要になる。
もしくは、　File > Packages > Update to Latest Package Versions　で最新バージョンにアップデートさせることも可能。
![スクリーンショット 2024-07-13 20.45.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3782130/ba53707c-a783-4f2e-cea7-0a6d85aa9799.png)

補足：他の項目は以下の意味となる
　Reset Package Caches：リセット
　Resolve Package Versions：依存関係を解決
　Update to Latest Package Versions：最新バージョンに更新

# 最後に
使用したいパッケージがSwift Package Managerにあるのであれば、
他のツールを使用するようりSwift Package Managerの方が良いかと思います。

地味にCocoa Podsとかインストールめんどいんですよね。。

以上
AWS Step Functionsとは

# はじめに

実はあまり触ったことがないStep Functionsを1から使いながら学んでいこうと思います！

# Step Functionsとは

分散アプリケーションの構築、プロセスの自動化、マイクロサービスのオーストレーション、データおよび機械学習の**パイプラインの作成に役立つワークフローサービス**です。
アプリケーションのワークフローを一連のイベント駆動型ステップとして使用することができます。

Step Fuctionsの組み込みコントロールを使用すると、ワークフローの各ステップの状態を調べて、アプリケーションが順番通りに実行されているか確認することができます。

# 特徴

- **Amazon States Language(ASL)** で記述される。
- **ステートマシン**として定義される
- **ステート**と呼ばれるステップで構成される
- 複数のAWSサービスの**オーケストレーション**に利用可能

# ステートマシン
**ワークフロー全体を定義する概念**であり、状態（ステート）とその間の遷移を構成することによって、複雑なプロセスを管理します。

# ステート

**ワークフローの各ステップを表す基本単位です。**
ステートは、それぞれ異なるタスクやアクションを実行するための定義です。各ステートは、次にどのステートに遷移するか、どのようなタスクを実行するか、エラーが発生した場合の処理方法などを指定します。

以下に、代表的なステートの種類です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1991303/246321cc-c4ed-ac0f-d66d-8d47c66415c2.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1991303/c5e8a5dd-689e-b4b9-3f54-d1867ccf2e39.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1991303/e93bb8b4-9349-0d67-21eb-9d457e8d4dc8.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1991303/71ff2744-9544-78ac-7577-b44e2f161478.png)

# AWS SDKと最適化された統合

他のAWSサービスを呼び出すためには2つの方法があります。

- AWS SDK統合による、ステートマシンから200を超えるサービスを直接呼び出す方法
- Step Functionsの最適化された統合は、カスタマイズされていてステートマシンで使いやすい

# ワークフロー

StandardワークフローとExpressワークフローがあります。

## Standardワークフロー仕様

実行時間が長い場合に最適です。
- １度だけワークフローが実行されて最大1年間実行することができる
- 毎秒2000の実行レート
- 毎秒4000のステート以降レート
- 実行履歴と視覚的なデバッグの表示
- すべてのサービス統合

## Expressワークフロー仕様
ストリーミングデータ処理や IoT データインジェストなどの high-event-rate ワークロードに最適です。
- at-least-onceワークフロー実行があり最大5分間実行することができる
- 毎秒100000の実行レート
- ほぼ無制限のステート移行レート
- 実行履歴をCloudWatchに送信する
- すべてのサービス統合

# まとめ

Step Functionsの基本的な概念について理解することができました。
今後、実際に触っていきたいと思います。
「Ctrl + C」で選択した文章を翻訳する。

Ctrl+Cを押したときにクリップボードの内容を翻訳し、表示するシンプルなツールを作成しました。Local LLMを用いて翻訳することで、機密文書などをネットワークを介してやり取りするのは「ちょっと」という方にとって、このツールは非常に有用です。

## 背景
最近、Ollamaさんのおかげで Local LLM がとても使いやすくなり、レスポンスも許容範囲内に収まってきました。そこで、この能力を無駄に翻訳に活用したいと思いました。

https://ollama.com/

## コンセプト
- Ctrl+Cを押した時にクリップボードの内容を翻訳し表示させること
- ローカルで完結させること


## 使用技術
- Python
- `pyperclip`：クリップボードの操作
- `pynput`：Ctrl＋C の検出
- `ollama`：ollamaの操作
- `tkinter`：UIの表示

## ツールの概要
このツールは、以下の手順で動作します。
1. Ctrl+Cが押されたときにクリップボードの内容を取得
2. 取得した内容を翻訳
3. 翻訳結果をウィンドウで表示

## コードの実装
詳細なコードはGitHubに公開しています。ぜひご覧ください。

https://github.com/GaneshaShiisa/Ctrl-C_Translator

以下に主要な部分のコードを示します。
### 1. Ctrl+Cの検出とクリップボードの操作
キーボードで押されたキーを監視し、Ctrl+Cが押されるのを待つ。
```python
from pynput import keyboard, mouse
import pyperclip

def ctrl(letter):
    return chr(ord(letter.upper())-64)

def on_release(key):
    try:
        if key.char == ctrl("c"):
            clipboard_text = pyperclip.paste()
            ## ここに、翻訳と表示のアクションを記述 ##
    except AttributeError:
        pass
        
def start_keyboard_listener():
    with keyboard.Listener(on_release=on_release) as listener:
        listener.join()

# キーボードリスナーを別のスレッドで実行
listener_thread = threading.Thread(target=start_keyboard_listener)
listener_thread.daemon = True
listener_thread.start()
```

### 2. `ollama`を使用して翻訳
`ollama`ライブラリを使用して、クリップボードの内容を翻訳します。
日本語と英語の両方が使えるため、翻訳もできるだろうという思い込みで、モデルは「gemma2」を使いました。
```python
response = ollama.generate(
    model="gemma2",
    prompt=f"Please translate '{clipboard_text}' into Japanese. Output only the translated Japanese text."
)
label.config(text=response['response'])
```

### 3. `tkinter`を使用して翻訳結果を表示
`tkinter`ライブラリを使用して、翻訳結果をポップアップウィンドウで表示します。これにより、ユーザーはすぐに翻訳結果を確認できます。
今回は、マウスの位置に表示しましたが、本当は選択した文章と併記したいと思っています。
事前にウィンドウを作成しておき、`root.withdraw()`で隠しておく。
```python
import tkinter

root = tkinter.Tk()
root.overrideredirect(True)
root.configure(bg="lightblue")

# ウィンドウを最前面に設定
root.attributes("-topmost", True)

root.withdraw()

label = tkinter.Label(root, text="Hello, tkinter!")
label.pack()
```
ウィンドウの表示位置を決め、`root.deiconify()`で再表示させる。
```python
root.geometry(f"+{x}+{y}")
root.deiconify()
```

## まとめ
このツールは、簡単にクリップボードの内容を翻訳し表示することができます。ブラウザでの翻訳は一般的になっていますが、PDFや他のアプリケーションでの翻訳には依然としてツールにコピペしてるため、このツールを使うことで翻訳作業が楽になります。また、選択した文章と併記して見ることが出来れば、英語の勉強にも役立つかと思います。

今後も使いやすさを追求して改良を続けていきます。皆さんもぜひ試してみてください！
33業種×エンジニア：建設業

## はじめに
未経験からのエンジニア転職を模索中。33業種それぞれでエンジニアはどのような働き方をしているのかが気になったので調べたことをまとめてみます。実際に現場で働いている方から見たらぬけ等あるかと思いますが、あたたかい目で見守ってください


## 建設業×エンジニアの働き方の例
![kennsetu.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3777936/9b78bf5f-3f2d-512d-b082-080519452543.jpeg)

### 構造エンジニア（Structural Engineer）
- 役割：建物やインフラの設計・解析を行い、構造の安全性や耐久性を確保する
- 具体例：高層ビルの耐震設計や橋梁の構造解析を行い、地震や風、荷重に耐える設計をする
- 該当会社：
世界大手：AECOM（エイコム）
日本：大成建設株式会社（Taisei Corporation）、鹿島建設株式会社（Kashima Corporation）

https://www.taisei.co.jp/

https://www.kajima.co.jp/


### 施工管理エンジニア（Construction Management Engineer）
- 役割：建設プロジェクトの計画、進行管理、品質管理、安全管理を行う
- 具体例：建設現場で工期の進行管理やコスト管理を行い、プロジェクトがスケジュール通りに進むように監督する
- 該当会社：
世界大手：Bechtel Corporation（ベクテル）
日本：清水建設株式会社（Shimizu Corporation）、竹中工務店（Takenaka Corporation）

https://www.shimz.co.jp/

https://www.takenaka.co.jp/

### 環境エンジニア（Environmental Engineer）
- 役割：建設プロジェクトが環境に与える影響を評価し、環境保護対策を立案・実施する
- 具体例：建設現場の土壌や水質の汚染防止対策を講じ、持続可能な建設を推進する
- 該当会社：
世界大手：Jacobs Engineering Group（ジェイコブス）
日本：大林組株式会社（Obayashi Corporation）、戸田建設株式会社（Toda Corporation）

https://www.obayashi.co.jp/

https://www.toda.co.jp/


### 設備エンジニア（M&E Engineer - Mechanical and Electrical Engineer）
- 役割：建物や施設の機械設備や電気設備の設計、施工管理、メンテナンスを行う
- 具体例：ビルの空調システムや電力供給システムの設計を行い、効率的で安全な設備運用を実現する
- 該当会社：
世界大手：Fluor Corporation（フルアー）
日本：高砂熱学工業株式会社（Takasago Thermal Engineering Co., Ltd.）、新菱冷熱工業株式会社（Shinryo Corporation）

https://www.tte-net.com/index.html

https://www.shinryo.com/


### 土木エンジニア（Civil Engineer）
- 役割：道路、橋梁、トンネル、ダムなどのインフラストラクチャーの設計、施工管理を行う
- 具体例：高速道路の設計や河川の護岸工事を計画・監督し、安全で効率的なインフラを整備する
- 該当会社：
世界大手：Skanska（スカンスカ）
日本：前田建設工業株式会社（Maeda Corporation）、東急建設株式会社（Tokyu Construction Co., Ltd.）

https://www.maeda.co.jp/

https://www.tokyu-cnst.co.jp/


## さいごに
建設業におけるエンジニアの役割は多岐にわたり、設計、施工管理、安全管理、環境保護など多くの分野で活躍していることを知ることができました。
1～5それぞれで該当会社を上げているのでそれだけに特化しているように見えますがそうではありません。どの会社も1～5ほぼ網羅していると思います（個人の見解です💦）特に施工管理なんてどの会社もあるはず。
2024・2025問題関連でのエンジニアのお仕事は多いのかもしれません
転職ドラフトでスタートアップに転職した体験談


転職ドラフトを利用して指名を頂き転職に成功したので、その体験談を書こうと思います。
なお、こちらの記事は[転職ドラフト体験談投稿キャンペーン](https://job-draft.jp/articles/251)に参加しています。

## 登録したきっかけ

### 前回の転職でも利用した

前回の転職でも「転職ドラフト」を利用して転職できたという成功体験があったので、今回も転職サイトは「転職ドラフト」1本に絞って活動しました。

### 指名時に年収が提示される

指名と同時に年収が提示される合理的なシステムでです。
そのため普通の転職でありがちな「オファー面談で初めて年収が提示され、希望より低くて断りたいけど次が見つかるかも分からないし…」と悩むようなことがありません。
年収のミスマッチを防ぎ時間の無駄を省くことで効率よく転職活動を進められます。

### 自分の市場価値の把握

指名されると指名理由、年収が提示されるため客観的な市場価値を知ることができます。
エンジニアにとって市場価値はキャリア形成においてとても重要ですが自分で知ることはできません。
市場価値を把握することで転職においても、転職後のキャリアにおいても有利にことを運ぶことができます。

## どんな指名を受けてどのように受け止めたか

今回は2件の指名を受けました。(内1件は1位指名)
どちらも現職と同程度の年収を提示されました。
どちらもきちんと職務経歴書を読んだうえで指名をしていることが分かり好印象をうけました。

転職ドラフトではテンプレのような指名理由はゼロではありませんが、比較的少ない印象です。

## 面談や面接へどんな期待をしてどのように臨んだか

企業のプロフィールからは読み取れない業務内容や社内の雰囲気が聞けることを期待して臨みました。
普通の転職のように提示年収がわからず面接中にやきもきすることもないのでスッキリした気持ちで面談に望むことができました。

## 参加前の予想と異なったことや印象的だったこと

前回利用時は5社〜10社から指名を頂いていましたが、今回は2社だけでした。
前回より自分の年収も上がっているので、それにより指名企業も減ってきたのだと思われます。

## 転職ドラフトへの改善要望

### 90%ルールの撤廃

面接を通過し、企業がオファーする際の提示年収は指名額の90%以上というルールがあります。
これを撤廃し指名額を最低年収として欲しいです。

自分も今回はオファー面談で指名額の90%を提示され、入社するか迷いましたし、一気にモチベーションが下がりました。
企業からは面接の結果、スキルや経験を踏まえてこの金額にした、と説明がありましたが真意のところはこちらには分かりません。
最初から90%にする前提で提示する企業も普通にあると思いますし、そうされたら誰にも分かりません。

## これから参加する方へのメッセージ

90%ルールを除けばエンジニアの転職サービスとしては非常によいサービスだと思います。
特にWeb系企業、スタートアップの参加率が高いのでそれらの業界に興味がある人は是非利用してみることをおすすめします。
CSSでのdisplayプロパティの活用と使い方の整理

# はじめに
displayプロパティを多様しているけど、よくわかっていない。
なんとなくで進めていくことにモヤったので、整理のためにまとめました。
特にボタンを作る時に使うんだろうけど、毎回なんか？？？てなる。


# 結論


**`flex`最強。**

`display: block;`　➡️　たて並びに：インライン要素にあてられる
`display: inline-block;`  ➡️　よこ並びに：インライン要素とブロック要素にあてられる
`display: flex;`　　➡️　　どの方向でも：ブロック要素かつ親要素にあてる

**`flex`最強。**

# ? displayプロパティってどんな使い方するの

要素の**表示方法**(縦横並び)を指定できる。

# 主要なdisplayプロパティの値とその使い方

**1.　`display: block;`**　：　インライン要素にあてる

インライン要素（a,span,imgなど）を**たて並び**に。
（ブロック要素のように高さと幅を自由に替えられる。）

**2.　`display: inline-block;`**　：　インライン要素とブロック要素にあてられる
インライン要素を**よこ並び**に。
（ブロック要素のように高さと幅を自由に替えられる。）

**3.　`display: flex;`**　：ブロック要素かつ親要素にあてる
`display: flex;`は親要素へ当てる。
そこにプロパティを追加することでフレックスコンテナ内の子要素を柔軟に配置できる。

【code】
```index.html
<div class="flex-container">
  <div class="flex-item">アイテム1</div>
  <div class="flex-item">アイテム2</div>
  <div class="flex-item">アイテム3</div>
</div>
```
```style.css
.flex-container {/* ← 親要素*/
  display: flex;
  justify-content: space-between; /* 子要素を均等に配置 */
  align-items: center; /* 子要素を縦方向に中央揃え */
  border: 1px solid #ccc;
  padding: 20px;
}

.flex-item {/*子要素自身のスタイルのみあてる*/
  background-color: lightblue;
  padding: 20px;
  margin: 5px;
}
```
【見た目】
![スクリーンショット 2024-07-13 20.43.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3830302/1f2ec0ef-7dd3-d81b-77ec-8ff6d06e0fcc.png)


**4. `display: inline;`**
ブロック要素をインライン要素にする。あんまり使わない。
・特徴: 他の要素と同じ行に並び、幅は内容に応じて決まる。
　　　  高さと幅を設定できない。→ `display: inline-block;`使った方がいじりやすい。

# おわりに
私が今知っている限りのdisplayプロパティはそんなに複雑じゃなかった。
親子要素の関係と表示（縦横）の2軸があるように感じていて、それがごちゃ混ぜになっていました。
ゆーて`flex`最強論があるようなので、その意味がわかるようになりたいです。

※初学者故に誤りがあるかもしれません。
もし親切な方がいらっしゃいましたら、ご指摘頂けますと幸いです。
よろしくお願いいたします。
33業種×エンジニア：鉱業

## はじめに
未経験からのエンジニア転職を模索中。33業種それぞれでエンジニアはどのような働き方をしているのかが気になったので調べたことをまとめてみます。実際に現場で働いている方から見たらぬけ等あるかと思いますが、あたたかい目で見守ってください

## 鉱業×エンジニアの働き方の例
![鉱山.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3777936/f84c1cb4-52f2-8d49-0435-6416b95eff38.jpeg)

### 鉱山エンジニア（Mining Engineer）
- 役割：鉱山の設計、計画、運営、閉鎖を行い、鉱床の評価、採掘計画の作成、環境影響評価、安全管理などを担当
- 具体例：新しい鉱山の開発において、最適な採掘方法を決定し、資源の最大化と環境保護のバランスを取る
- 該当会社：リオ・ティント（Rio Tinto）、三菱マテリアル株式会社

https://www.mmc.co.jp/corporate/ja/

https://riotintojapan.com/


### 地質エンジニア（Geological Engineer）
- 役割：鉱床の探査、評価、地質データの解析を行い、地下の鉱物資源を特定し、その量と質を評価する
- 具体例：地質調査を行い、鉱床モデルを作成して、鉱床の位置や規模を予測する
- 該当会社：ニュークレスト・マイニング（Newcrest Mining）、三井金属鉱業株式会社、

https://www.mitsui-kinzoku.com/

https://hd.dowa.co.jp/ja/index.html


### 冶金エンジニア（Metallurgical Engineer）
- 役割：採掘された鉱石から金属を抽出・精製するプロセスを設計、管理し、精錬、濃縮、製錬のプロセスを最適化する
- 具体例：新しい抽出技術を開発し、採掘コストの削減と金属回収率の向上を図っている
- 該当会社：フリーポート・マクモラン（Freeport-McMoRan）、日鉄鉱業株式会社、JX金属株式会社

https://www.jx-nmm.com/

https://www.nittetsukou.co.jp/


### 環境エンジニア（Environmental Engineer）
- 役割：鉱業活動が環境に与える影響を評価し、環境保護対策を計画・実施する。鉱山閉鎖後の環境復旧も担当する
- 具体例：鉱山の廃棄物管理システムを設計し、鉱山廃水の処理方法を開発する
- 該当会社：アンガロ・アシャンティ（AngloGold Ashanti）、三菱マテリアル株式会社、住友金属鉱山株式会社


### 安全エンジニア（Safety Engineer）
- 役割：鉱山で働く従業員の安全を確保するための安全管理体制を設計・実施する。リスク評価、労働安全衛生プログラムの実施を行う
- 具体例：安全プロトコルを作成し、定期的な安全訓練を実施して、労働災害のリスクを最小化する
- 該当会社：サウス32（South32）、三井金属鉱業株式会社、DOWAホールディングス株式会社

## さいごに
鉱業でエンジニアは想像できていませんでしたが、安全面やシステムにおいて確かに必要な場面があることを知りました。鉱業という事もあり規模が大きそうなイメージです。
ChatGPT部 #46 部活動レポート


遅刻しました、すみません
先週なかったのでウッカリしてました…！

## 本日のイベント
https://chatgptclub.connpass.com/event/324845/

## 部長挨拶
- ChatGPT活用マニュアル作ってるよ
- AGI福岡
  - 立ち上げ期で色々やってます、オンライン参加もできるよ！

https://agifukuoka.connpass.com/

## 鈴木トミ爺さんのインタビュー
シニアエンジニア勉強会のおはなし
台湾のメディアにまで展開！

 > 89歳アプリ開発者としてシニアの会でアプリの発表を行った時AFPからインタビューを受けました。
それが台湾メディアやフランスで動画で放映されました。

https://news.pts.org.tw/article/701243

https://www.youtube.com/watch?v=R6gruYV-C5U

もっと国内でも評価されるべき！私もそう思います。

## LTコーナー
### API費用と時給から考えるマルチモーダルなAIとの協業時期
AGI福岡でもされたお話のこと

電気代とかイニシャルコストの話をするとややこしいので、あくまでAPI利用に限った内容にフォーカス
人間の１時間との費用を比較するのが本旨のため
業務内容を棚卸しして、AIが介在する時にいくらかかるか？という議論が主論ながら、運用を考えると時間がどれぐらい掛かるかな？という観点が魅力だと私は思っているので、一旦はその観点はなしかなぁ。
↑結論部分でお話しありました。ここは同感です。

質疑応答で人を１人で働かせるよりはAIで代替できるかどうか？が観点としてある

### 「10倍速で成果が出る！ChatGPTスゴ技大全」を読む
私が話すだけ

https://qiita.com/nomurasan/items/fc290094364e00664656

質疑応答で、本の発行日とChatGPTのバージョンとかは明記されているか？とのこと。
ハルシネーション回避のために生成結果とか出さなかったんだろうな、という所感をそのまま伝えてます。

## ディスカッション： 本を書くとしてどうしよう？
- 業務利用のための運用とは？
- AIサービスをサマリーしてみる
- 版上げを考えた時に書籍だとやりにくいなぁ

などなど、課題が色々

## 所感
今日のメインコンテンツはトミ爺！
グローバル展開はすごい！
【Unity】MiniMax法で〇✖ゲームのAIを実装する

今回も、[前回](https://qiita.com/GameDevEgg/items/4c231e419dd2644baf04)までの続きです。
〇✖ゲームの実装自体は前回で終えたので、今回はMiniMax法でAIを実装します。

# MiniMax法とは？

MiniMax法とは、簡単に言うと、

「プレイヤー（自分）は自分にとって最も有利な手を選び（最大化）、
相手は自分にとって最も不利な手を選ぶ（最小化）」と仮定した上で、
再帰的に最善の手を求めるアプローチのことです。

詳しくは、[Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%9F%E3%83%8B%E3%83%9E%E3%83%83%E3%82%AF%E3%82%B9%E6%B3%95) の内容をご覧ください。

# MiniMax法による最善手の探索

MiniMax()メソッドがMiniMax法による最善手の探索を行っています。

MiniMax()メソッド自体が再帰的に処理を行っているため、
ChangeBestCellSprite()メソッド ~~（命名テキトーすぎる）~~ は最初の呼び出しのみ行います。

MiniMax()内で引数のフラグが逆のMiniMax()を呼び出しているのは、
自分（AI）と相手（Player）の手を交互に想定しているからです。

```cs
// 最善手のセルのスプライトを変更する
private void ChangeBestCellSprite()
{
    int bestScore = int.MinValue;
    int row = -1;
    int column = -1;

    for (int r = 0; r < Size; r++)
    {
        for (int c = 0; c < Size; c++)
        {
            if (cells[r, c].sprite == null)
            {
                cells[r, c].sprite = cross;
                int score = Minimax(0, false);
                cells[r, c].sprite = null;

                if (score > bestScore)
                {
                    bestScore = score;
                    row = r;
                    column = c;
                }
            }
        }
    }

    if (row != -1 && column != -1 && cells[row, column].sprite == null)
    {
        cells[row, column].sprite = cross;
    }
}

// 再帰的に現在の一手を評価する
int Minimax(int depth, bool isMaximizing)
{
    if (IsWin())
    {
        return isMaximizing ? -1 : 1;
    }
    if (IsDraw())
    {
        return 0;
    }

    if (isMaximizing)
    {
        int bestScore = int.MinValue;

        for (int r = 0; r < Size; r++)
        {
            for (int c = 0; c < Size; c++)
            {
                if (cells[r, c].sprite == null)
                {
                    cells[r, c].sprite = cross;

                    int score = Minimax(depth + 1, false);

                    cells[r, c].sprite = null;

                    bestScore = Mathf.Max(score, bestScore);
                }
            }
        }
        return bestScore;
    }

    // 相手が自分のスコアを最小化するように行動すると仮定
    else
    {
        int bestScore = int.MaxValue;

        for (int r = 0; r < Size; r++)
        {
            for (int c = 0; c < Size; c++)
            {
                if (cells[r, c].sprite == null)
                {
                    cells[r, c].sprite = circle;

                    int score = Minimax(depth + 1, true);

                    cells[r, c].sprite = null;

                    bestScore = Mathf.Min(score, bestScore);
                }
            }
        }
        return bestScore;
    }
}
```

このコードを実行すると、AIが確実に中央（1, 1）のセルを埋めに来るのが分かります。
また、プレイヤー（自分）がリーチになると、必ずゴールを阻止してきます。

# おわりに

完璧とは程遠い実装ですが、MiniMax法としてのアプローチが出来ているはずです。
今後は、もっと高度なAIの動きにチャレンジしていきたいと思います。

最後までご覧いただきありがとうございました :laughing:
Rustで文字列の出現回数を数えたい

Rustで文字列の出現回数を数えたい場合、`matches`と`count`を利用します。

```rust
let s = "abcXXXabcYYYabc";
println!("{}", s.matches('a').count()); //=> 3
```

**環境情報**

```
$ rustc -V
rustc 1.75.0 (82e1608df 2023-12-21)
```


**参考**

https://doc.rust-lang.org/std/primitive.str.html#method.matches
法学部の奴が3か月で基本情報技術者試験した合格

# 1.結果

|  午前  | 午後 |
|:--------------:|:------------:|
|     875   |    710   | 　

**合格！！**
午後問題は自信がなかったのですが無事に合格することが出来ました。

# 2.受けた理由

### CSの基礎知識を身につけたかった
私は文系大学出身なのでITの基礎を勉強したことがありません。まずは基礎を身につけることにより今後の成長の幅が広がると思いましたCS専攻の学生が大学で学ぶ内容を広く浅く網羅できる

### 勉強しやすかった
というのも、私は、大学2年の春休みに宅建（不動産取引に関する法律系の資格）をとっつきにくさや試験が年に一度しかなく勉強に身が入らず挫折した経験がありましたが、基本情報技術者は、通用受験できる点や、勉強内容も長年謎だった「コンピューターってなんで動いているの？」っていうのがなんとなくわかってきたり「コンピューターって0と1だけでできてんの⁈なにそれくそおもしれーじゃん。」みたいな感じで、聞いたことある単語の意味など興味深いものが多くどんどん知識を吸収出来ました。

# 3.参考物
### 参考書
◾️キタミ式イラストIT塾 基本情報技術者 令和06年
![kitamisiki.qiita.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3809793/34ff2800-7119-314d-3df7-d3129bba9a38.jpeg)

◾️情報処理教科書 出るとこだけ！基本情報技術者［科目B］第4版
![derutokodake.qiita.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3809793/d9d6dce8-44e7-947a-6dc1-015ac9116ecb.jpeg)

### サイト

https://www.youtube.com/@kihonzyouhou

https://www.fe-siken.com/fekakomon.php

### スマホアプリ
https://apps.apple.com/jp/app/%E5%9F%BA%E6%9C%AC%E6%83%85%E5%A0%B1%E6%8A%80%E8%A1%93%E8%80%85%E8%A9%A6%E9%A8%93-%E7%A7%91%E7%9B%AEa-%E7%A7%91%E7%9B%AEb-%E5%85%A8%E5%95%8F%E8%A7%A3%E8%AA%AC/id1644966017

# 4.勉強方法
### 科目A
私は、動画学習が好きだったのですーさんのYouTube動画でノートに取りながら一周し、電車などでスマホのアプリの過去問を前日やった範囲などをおいおいやっていくようにしていました。ただこのアプリの解説は少し短めなので、わからないところは過去問道場の解説を参考にしていました。問題文をそのままGoogle検索すれば、過去問道場の該当設問がヒットします。間違えた箇所に関してはアプリ上でチェックを入れておけるので便利です。すーさんの動画に関しては、イラスト付きで非常にわかりやいのでおすすめです。また、すーさんの動画は進みがキタミ式の参考書と似ているのですーさんの動画で学習を進める方はかやのき先生ではなくキタミ式をおすすめします。すーさんの動画を一周したら、すぐに過去問道場で過去問を解き始めました。わからない問題は、答えを見る前にノートや参考書を見直して解くようにしています。この方法は、河野玄斗さんの資格勉強法に基づいており、非常に効率が良いと思ったので、ぜひ試してみてください。


https://www.youtube.com/watch?v=jV6l-MbKjLU


### 科目B
午後対策は情報処理教科書 出るとこだけ！で勉強。最初どう対策しようか迷ったがこの書籍は、出題の傾向を把握できるので、効率的に対策すべき分野を知ることができる。図解が丁寧で、初学者にもわかりやすく午後問題をどうやって読んで解いていくのかが分かった。私は、基本情報技術者の勉強と並行してProgateやUdemyでプログラミング学習を進めており、JavaScriptの基礎構文くらいはわかっていたのでデータ構造及びアルゴリズムの分野は文系や初学者の方はつまずきやすいと思うんですが、私は、スムーズに学習できたので、資格勉強の合間などに気分転換にプログラミング学習も並行して進めるのはおすすめしたいです。しかし、情報セキュリティの分野は全然っわからなかったので、問題をこなして対策しましたが、最後まで自信を持てませんでした。試験前は、すーさんの３時間越えの動画見て詰め込んで行きました。これもおすすめです。

# 5.おわりに
受けてよかったことは、二つほどあり、一つは、プログラミング学習の理解度が上がった点です。Progateをやるにしても最初は「ディレクトリってなんだよ」などわからない単語があると学習が止まるし理解度も下がってしまいますがそれが減りました。二つ目は、基本情報技術者試験に合格したことにより、自分はITの基礎知識があるという自信がもてました。また、エンジニアのインターンなどでも、ある程度ついていけるようになったと思いまが、コーディングとかはまだくそザコなので頑張ります。応用情報技術者試験もこのまま受けようと思ったんですが、ポートフォリオ作成やコーディングテスト対策などやることが多かったので、就活が終わってから受けようかと思ってます。

# 6.今後の目標
自己紹介サイトなんとなく出来上がったのでQiita紹介すること。また、WEBアプリ作成に向けてサーバーサイドの勉強をする。夏はちょっと厳しいので秋のインターンで複数daysのエンジニアインターンに行けるよう日々勉強すること。しっかりスケジュールを練って少しずつ進めていこうと思います。
【セッションレポート】「使い慣れたSQLに潜む実装依存」に参加しました

# はじめに
本記事はDB Tech Showcase 2024 の2日目(7/12)において HPE の篠田さんが講演された「使い慣れたSQLに潜む実装依存」のレポートです。

# 公式セッション紹介
> Oracle Database 23aiでは一部のPostgreSQLやMySQL構文がサポートされるようになりましたが動作が異なる部分もあります。いつも普通に使っているSQL文や関数の微妙な動作の違いについて、代表的なRDBMSを使って説明します。

# 発表資料

- [使い慣れたSQLに潜む実装依存](https://speakerdeck.com/nori_shinoda/implementation-dependencies-in-the-commonly-used-sql)

# 概要／おすすめポイント

リレーショナルデータベースにおけるデータベースエンジンの差については、ある程度認識が共有されていると思います。

データベースエンジンの変更において特にアプリケーション側に影響がある変更点としてはSQLの実装の差があります。大前提としてSQL標準に沿ったSQLは、基本的にはどのデータベースエンジンでも同じ結果が得られますが、一方で、実装の差によって違った結果が得られる場合もあります。
本セッションではその実装の差による結果の違いについて、実際に実行したSQL文と結果を例に紹介されています。
差があるのは知っていても実際にどうなるのか知りたい方は、是非発表資料の例を参照してみてください。

複雑なSQL文ではなく、1行コピペですぐに試せるSQLですので、実際に手元の環境で叩いて確認しても面白いかと思います。

# セッション内容の紹介

セッションでは以下の区分においてそれぞれで幾つか例を挙げて差を説明されてました。

- 構文
- 関数
- データ型と演算子

特にエラーになるものよりも、エラーなく実行はできるが結果(アウトプット)が違うものについて~~楽しそうに~~説明されていたのが印象的でした。

個人的には構文の中の「トランザクション中のエラー」や有名なOracle DatabaseにおけるNULLの扱いが、PostgreSQLへのマイグレを行う際によく注意点としてあがるので興味を引きました。

# まとめ

一般的にデータベースエンジンによって結果に違いがある、という知識とデータベースエンジン変更の際に注意する点としての認識はもっていましたが、今回のセッションでは構文や関数などそれぞれのデータベースエンジンの実装によって違いがある部分について、それぞれ実際の結果が例示されていてわかりやすかったです。

実際に **互換** とされているデータベースエンジン、例えば MySQL と TiDB や Spanner の PostgreSQL Interfaceとかで試すとどうなるか、機会があったら試してみようと思いました。

# おまけ

よく検討されるデータベースエンジンの変更としては、Oracle DatabaseからPostgreSQLへの変更などが挙げられます。今回のようなSQLの実装の違い以外にもオブジェクトの差分などを見つけてサジェストしてくれたりします。
代表的なツールはクラウドのツールが多いですが、DBTSのオーガナイザのインサイトテクノロジーさんもInsight Data Testingを出してます(今回もセッションありましたが聞けず・・・)。

- [Insight Data Testing](https://www.insight-tec.com/products/sqltesting/)
- [AWS SCT](https://pages.awscloud.com/rs/112-TZM-766/images/20220623_19th_ISV_DiveDeepSeminar_SchmaConversionTool.pdf)
- [Google Cloud: Database Migration Service](https://cloud.google.com/blog/ja/products/databases/gemini-helps-migrate-oracle-to-postgresql-on-google-cloud)
Android Studio, Xcode でのアプリローカライズ方法


Android Studio には jetpack compose, Xcode は SwiftUI を使ったプロジェクトがある状態です。

## 作業環境
2024/7/13 現在
### Android Studio
Android Studio Koala
使用しているプロジェクト: Jetpack Compose で作成したアプリ

https://developer.android.com/studio

### Xcode
Xcode 15
使用しているプロジェクト: SwiftUI で作成したアプリ

https://apps.apple.com/us/app/xcode/id497799835


## Android Studio
1. プロジェクトファイルの中から string ディレクトリを探します
2. 選択した状態で右クリックをします
3. メニューから open translations editor をクリックします
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2747809/9a09dbd4-3625-9385-e1de-6e3d35e10203.png width=400> <br>
4. 地球儀マークの近くにある + マークをクリックしてプルダウンメニューの中から追加したい言語をクリックします
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2747809/3fa4a19b-ce59-d31e-2bc8-52f3d0533147.png width=400> <br>
5. それぞれの言語の文章を入力します
6. Jetpack Compose 上で stringResource(id = R.string.appName) のように使用したい文字列リソース ID を宣言します
例)
`Text(text = stringResource(id = R.string.landmark_number)`
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2747809/303f866b-9aa2-d7e4-4513-62a28f01523a.png width=400> <br>
7. アプリをビルドすると言語設定に従って文字列が変化することを確認できます
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2747809/6b5e2a3b-c6dd-db9a-2644-345bc7aa20d8.gif width=350>


## Xcode
1. プロジェクトファイルを選択する
2. Localizations というリストの下にある ＋ をクリックする
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2747809/85b12509-c27f-bdc9-f16c-9298a73c6152.png width=400> <br>
3. 追加したい言語をプルダウンメニューから探してクリックする
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2747809/b8e9b974-78ff-48ed-b995-4fde6a0e3471.png width=400> <br>
4. File -> New -> File をクリック
4. <img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2747809/4fcc1225-c61e-f625-57c4-b0bf23fa959e.png width=400> <br>
5. String Catalog をクリックしてファイルを追加する
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2747809/f1c20b53-7b23-0acf-51de-6255b1749c36.png width=400> <br>
6.  すでにSwiftUI にTextが打ち込まれているのであればProduct -> Build で String Catalog にkey と value が追加されます
7. それぞれの言語でローカライズしたい文字列を入力します
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2747809/19c3ea1e-9c34-86c9-fb49-75933c56e3fa.png width=400> <br>
Text 内に入力されている文字列が key の役割を果たします。
`Text("Favorite Landmarks only display")`
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2747809/c3e761dc-f081-fce4-c933-3fd482d3e9a9.png width=400> <br>
8. アプリを動かすと Text で定義されている文字列が言語設定に従って変化することが確認できます
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2747809/dbc2a3c4-0334-913e-1d6a-1adff7eb2896.gif width=350>



## 筆者の感想
Android Studio では`stringResource()`の中にID を入力しないと使えないが、Xcode ではそうした必要なく Text の中にある文字列がそのまま key になってくれるのが、とても楽だと感じました。

そのかわり重複に十分注意をしなければならない部分であるため、その点を留意する必要がありそうです。
JavaScriptでN番目の子要素を削除するにはchildrenを使う

# はじめに

JavaScriptでN番目の子要素を削除する方法について。

主な方法は2つ。

1. 親要素のchildrenプロパティで子要素のDOMを取得して削除
2. nth-child使って削除（コメントを参照）

# 解決方法

単純に1つの子要素を削除する場合。
（nth-childを使う場合でも任意の子要素を削除できます。）
~~『子要素のN番目』を削除できるので、子要素に何が来るか分からない場合に使うと良い。~~
またNは0からカウントする。

```javascript
const delIndex = N; // Nは0以上の整数
const parentNode = document.getElementById('parent');
parentNode.children[delIndex].remove();

```

## コメントより

子要素を指定して削除する場合。
（前述の通り、divの記述をなくせば任意の子要素を削除できます）
~~『N番目のELE』を指定して削除するので、子要素が確実にELEの場合に使うと良い。~~
またNは1からカウントする。

```javascript
const delIndex = N; // Nは自然数（1以上の整数）
// 【不要】const delTag = ELE; // ELEはHTMLタグ名（divなど）
// 【不要】document.querySelector(`#parent ${delTag}:nth-child(${delIndex})`)?.remove();
document.querySelector(`#parent :nth-child(${delIndex})`)?.remove();

```


# 拡張

複数の子要素を削除する場合は、こんな感じで使うのも手。

```javascript
const indexArr = [...]; // 0以上の整数N
indexArr.sort((a,b) => b - a);

const parentNode = document.getElementById('parent');
indexArr.map(i => {
  if (parentNode.children.length > i) {
    parentNode.children[i].remove();
  }
});
```

# 参考

https://developer.mozilla.org/ja/docs/Web/API/Element/remove

https://developer.mozilla.org/ja/docs/Web/API/Node/removeChild

https://developer.mozilla.org/ja/docs/Web/API/Element/children
Markdown AIはWebサイトを気軽に作りたい方に向いてそう

# はじめに
こんにちは、H×Hのセンリツ大好きエンジニアです。（同担OKです😉）
Markdown AIを使った記事を投稿しよう！というキャンペーンがありましたので、Markdown AIを使ってみました！

https://qiita.com/official-events/142fdd0d69ff6bb2d547

所感としては、**HTMLとかCSSとか、Webサイトの公開方法とか分からないけどWebサイト作ってみたい！** という方向けだと思いました🤩
※まだβ版とのことで、AIを活用することは出来ないとのことです🥲

# Markdown AIとは

https://mdown.ai/content?id=335b81b2-bcb0-4dbb-83d0-531aa132181f

**Markdownを使ってWebサイトを作成することができるサービス**のようです。
また、Webサイトの作成から公開まで全てを１つの画面で完結できるため、Webサイト制作に興味のある方でも始めやすいサービスとなってます！

さらに、**HTMLは普通に使えるので勉強中の方が試しに公開してみる**というユースケースも考えられそうですね🤔

### メリット
- 作成から公開まで**無料!!!**
- 出来ることが限られているため、初学者にとって覚えやすい
- Webサイトを気軽に公開できる

# Webサイト作成から公開まで
以下のページで実際に作成できます。

https://mdown.ai/file

初期画面はこちらになってます。
![スクリーンショット 2024-07-13 14.54.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653241/3e439d6b-c235-ac34-d3c0-a2f604d0b066.png)


それぞれの機能をセクションに分けて説明します！

### <font color="Red">1. Webサイトのページ管理</font>
こちらは、Webサイトを公開するページを管理するセクションです。
以下のものができます。
- ＋ボタンでページ追加
- Delボタンでページ削除
- 各ページクリックで切り替え

### <font color="Blue">2. Webサイトの見た目、画像挿入、公開</font>
こちらのセクションでは、以下のことができます。
- ViewボタンでWebサイトの見た目を確認
- Imageボタンで画像挿入
- Saveボタンで現在の変更を保存＆公開

### <font color="Green">3. Webサイトの中身を作成</font>
こちらのセクションでは実際にWebサイトをMarkdownで作成できます。


１画面で完結するので、直感で作業できそうです！便利ですね🥹
では、実際に作ってみましょう！
今回は、僕の大好きなハンターハンターのセンリツ紹介サイトを作ってみます！

``` sample.md
# **🎶 センリツ - 調律師の音色 🎶**

---


![スクリーンショット 2024-07-12 4.44.23.png](https://storage.googleapis.com/topdowncom/content/RWyVcJsYqXXxpP6BLJSOimvShha2/d018cd32-fecc-4275-acaf-a1c2fd99c4f1/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%202024-07-12%204.44.23.png)

---

## **プロフィール**

- **名前**: センリツ
- **職業**: 調律師
- **所属**: ハンター協会

---

## **特徴**

- **🎻 音楽への深い愛情**: 音楽と共に生きるセンリツは、その繊細な音感で世界を調律します。
- **🩸 呪いの影響**: 呪いにより変わり果てた姿を持ちながらも、その心は純粋で温かい。
- **🕊️ 平和を願う心**: 常に平和を望み、争いを避けるために努力しています。

---

## **エピソード**

> "私は音楽で世界を癒したい。人々の心に響く旋律を奏でるために、ここにいるのです。"

---

## **スキル**

- **🎵 音楽療法**: 音楽を使って人々の心を癒すことができます。
- **🔧 調律**: 楽器の調律だけでなく、心の調律も得意です。

---

## **リンク**

- [ハンターハンター公式サイト](https://www.shonenjump.com/j/rensai/hunter.html)
- [センリツの詳細情報](https://dic.pixiv.net/a/%E3%82%BB%E3%83%B3%E3%83%AA%E3%83%84)

---

センリツの物語はまだ続きます。彼女の音楽があなたの心にも響きますように。

```

このように記述すると。。。
![スクリーンショット 2024-07-13 15.45.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653241/557c3621-67fb-bf53-1644-99e2b319b3c3.png)

きちんと描画されていることが確認できますね！

また、Saveボタンを押すと、隣にURLボタンが出現します。
![スクリーンショット 2024-07-13 15.47.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653241/89d7d743-537c-310e-6111-f70766b92f6a.png)

これを押すとWebサイトを公開するか確認されますので、Publishボタンを押してみましょう！
![スクリーンショット 2024-07-13 15.47.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653241/6a886359-af37-f4a8-bb4d-87f73e054a62.png)

すると、簡単にWebサイトを公開することが出来ました！！！
とても簡単に作成から公開まで行えるので取っ掛かりやすいですね！🥳
↓↓↓こちらで確認できます。

https://storage.googleapis.com/topdowncom/content/RWyVcJsYqXXxpP6BLJSOimvShha2/d018cd32-fecc-4275-acaf-a1c2fd99c4f1/index.html

# おわりに
今回はキャンペーンを行っていたので、Markdown AIを触ってみました！
公開まで無料なので、気軽に触ってみたい方にはとてもオススメできるサービスかなと思います！

最後までご覧いただきありがとうございました🫡
【Go】スタックとヒープについて簡単なサンプルで確認する

## はじめに
メモリ領域にはスタックとヒープがあります。
スタックは関数呼び出しやその中で使われるローカル変数などが格納されるメモリ領域。
ヒープは動的にメモリが割り当てられる領域で、サイズの決まっていないデータや関数外で参照されたりする場合に使用するメモリ領域。

ヒープが大量に使用されてしまうと処理動作が遅くなるため、パフォーマンス改善をしていく際にこれらの知識が必要そうだったので、サンプルコードで確認したいと思います。

## コード
```go
package main

// スタック上に割り当て
func stackExample() int {
	x := 42
	y := x + 1
	return y
}

// ヒープ上に割り当て
func heapExample() *int {
	z := 42
	return &z
}

func main() {
	_ = stackExample()

	_ = heapExample()
}
```

## 動かしてみる
コンパイルする際に、-gcflags -mをつけると、エスケープ解析のログを出力することができます。
このエスケープ解析というもので変数をスタックからヒープに移動させるかどうかを判別しているようです。
```zsh
go build -gcflags -m main.go
```

stackExampleのx,yはエスケープされていません。
heapExampleのzはポインタを返しており、関数外で参照される可能性があるためヒープに移動されています。
```zsh
# command-line-arguments
./main.go:3:6: can inline stackExample
./main.go:9:6: can inline heapExample
./main.go:14:6: can inline main
./main.go:15:18: inlining call to stackExample
./main.go:17:17: inlining call to heapExample
./main.go:10:2: moved to heap: z
```
【Go言語】浮動小数点

# 浮動小数点

Goには2つの浮動小数点型がある。

* float32
* float64

[Go Playground](https://go.dev/play/p/R-kzEajzx7n)

```go
var n float32 = 1.0001
fmt.Println(n * n) // 1.0002
```

1.0001 * 1.0001 = 1.00020001ですが、1.0002と出力されます。

小数点は無限に存在するが、float64は有限の64bitである。そのため、丸め誤差が生じ、精度が落ちる時がある。

単精度浮動小数点(float32) : 指数が8ビット、23ビットが仮数を表す。
倍精度浮動小数点型(float64) : 指数が11ビット、仮数が52ビット、残りは符号となる。

符号 $S$ 、仮数 $F$ 、指数 $E$ とすると、10進数 $a$ は以下のようになる。

$ a = (-1)^ S \times F \times 2^E $

1.0001を上記の式で表すと、

```math
1.0001 = 1  \times 1.000100016593933 \times 2^0
```

となるので、1.0001を`float32`で表すと、以下のようになる。

| 符号 | 指数(8bit) | 仮数(23bit) |
|:-:|:-:|:-:|
| 0  | 01111111  | 00000000000001101000111  |

# 近似値を使うことによる弊害

## 比較

近似値を使うことで、`==`を使用した比較が不正確になる場合がある。

goのテストライブラリ[testify](https://github.com/stretchr/testify) には比較している値が$\delta$の範囲内であることを検査するための[InDelta](https://pkg.go.dev/github.com/stretchr/testify/assert#InDelta)が存在する。

## プロセッサに依存する

プロセッサには、浮動小数点演算を処理する浮動小数点演算ユニット(Floating Point Unit, FPU)を持っている。
処理結果はFPUに依存するので、FPUが異なる別のマシンで同じ結果になる保証はない。

こちらも$\delta$を考えることで解決する。

## 特殊な浮動小数点数

* 正の無限
* 負の無限
* NaN(Not-aNumber)

NaNは`f != f`を満たす唯一の浮動小数点数である。

これらの3つの浮動小数点数は以下のように作成される。

[Go Playground](https://go.dev/play/p/mVazKMJ3biP)

```go
func main() {
	var a float64
	positiveInf := 1 / a
	negativeInf := -1 / a
	nan := a / a
	fmt.Println(positiveInf, negativeInf, nan) // +Inf -Inf NaN
}
```

これら3つの浮動小数点数についての比較は、`math.IsInf`(無限)で、`math.IsNan`(NaN)で比較できる。

## 誤差の蓄積

### 加算・減算

以下のコードは10000に1.0001をn回加算プログラム。

```go
func f1(n int) float64 {
	result := 10_000.
	for i := 0; i < n; i++ {
		result += 1.0001
	}
	return result
}
```

それに対して、`f2`は1.0001をn回加算して、最後に10000を加算するプログラム。

```go
func f2(n int) float64 {
	result := 0.
	for i := 0; i < n; i++ {
		result += 1.0001
	}
	return result + 10_000.
}
```

nの値を変えて実行すると、

```go
func main() {
	n1 := 10
	fmt.Println(f1(n1), f2(n1)) // 10010.000999999993 10010.001
	n2 := 1000
	fmt.Println(f1(n2), f2(n2)) // 11000.099999999293 11000.099999999982
	n3 := 1000000
	fmt.Println(f1(n3), f2(n3)) // 1.0100999999761417e+06 1.0100999999766762e+06
}
```

nが大きくなるにつれて誤差が大きくなる。しかし、f2の方が精度は高い。

| n | 正確な値 | f1 | f2 |
|:-:|:-:|:-:|:-:|
| 10  | 10010.001  | 10010.000999999993  | 10010.001  |
| 1k  | 11000.1  | 11000.099999999293  | 11000.099999999982  |
| 1m  | 1.0101e+06  | 1.0100999999761417e+06  | 1.0100999999766762e+06  |

加算や減算を連続して行う場合は、大きさの近い値をまとめて計算してから、大きな値を加算・減算することで、誤差が小さくなる。

### 乗算・除算

$a \times (b+c)$ と $ a \times b + a \times c$ の結果は異なる。

```go
func main() {
	a := 100000.001
	b := 1.0001
	c := 1.0002

	fmt.Println(a * (b + c)) // 200030.00200030004
	fmt.Println(a*b + a*c) // 200030.0020003
}
```

$ a \times b + a \times c$ の方が誤差が小さくなる。
乗算と除算は、加算・減算より先に行うことで、誤差を小さくすることができる。

# まとめ

* Goのfloat32, float64は近似値をとるので、誤差が発生する
* 加算・減算は同じ桁数の演算をまとめて行うことで、精度が上がる
* 四則演算が混合する場合、乗算と除算を先に行うことで、精度が上がる