OmniAICreator/Qiita-1.07M huggingface dataset:
LambdaからFargateへの切り替える際にNode.jsアプリのタスクスペックをどう決めたか？

最近、LambdaからFargateに移行して、Node.js(NestJS)アプリの動作を最適化するためにタスクスペック(CPUやメモリの割り当て)についていろいろ試行錯誤しました。この経験を踏まえて、最適な設定を見つけるまでの流れを共有します。

## Lambdaとの違い
最初はLambdaを使っていたんですが、リクエストごとに新しい環境が立ち上がり、リソースの競合がなくて快適でした。短い処理ならLambdaが効率的で、オートスケーリングも自動的に対応してくれていました。

でも、長時間稼働するバッチ処理や大量データの処理になると、Lambdaではコールドスタートやタイムアウト(30 s)が気になってきました。そこで、より柔軟なリソース管理ができるFargateに移行することに決めました。

## Fargateに移行してみて: タスクスペックの試行錯誤
Fargateの強みは、CPUやメモリなどのリソースを自分で細かく設定できるところですが、これが逆に難しくもあります。Node.jsはシングルスレッドで動くので、どのくらいのリソースが最適なのかを見極める必要がありました。

### 1vCPU 2048MB の場合
まず試したのがこの構成ですが、Node.jsのデフォルトヒープメモリ制限にすぐに引っかかり、メモリ不足が頻発しました。大量データの処理では、ガベージコレクションが頻発してタスクが落ちてしまうことが多く、パフォーマンスがかなり不安定でした。

### 2vCPU 4096MB の場合
ここでメモリを倍にしてCPUも増やしたところ、パフォーマンスが大幅に向上しました。Node.jsのシングルスレッド特性を活かしながら、バックグラウンドの処理(ガベージコレクションや I/O 操作)が別のコアで処理されることで、全体的なスループットが向上しました。このスペックは、かなりいい感じで落ち着きました。

### 4vCPU 8184MB の場合
もっとリソースを割り当てればレイテンシーが下がるんじゃね？と思い、4vCPUに増やしましたが、これは失敗でした。Node.jsのシングルスレッドでは、余ったCPUリソースを有効活用できないため、逆にオーバーヘッドが増えてパフォーマンスが低下しました。リソースの過剰割り当ては無駄が生じるだけでなく、パフォーマンスを逆に悪化させることを学びました。

## オートスケーリングの設定
Fargateを使う上で、タスクの数をどう増減させるかというのは非常に重要なポイントです。設定したタスクスペックは「**2vCPU 4096MB**」でしたが、このスペックにしてからオートスケーリングの効果が格段に感じられるようになりました。

### 2vCPU 4096MB に設定した利点
この構成を選んだ理由は、Node.jsのシングルスレッド処理に対して最適なバランスを取れることです。1vCPU だとメインスレッドがリクエスト処理に使われてしまい、ガベージコレクションや I/O 処理でメモリや CPU が圧迫され、結果的にパフォーマンスが低下していました。しかし、2vCPUにすることで、メインスレッドはリクエスト処理に専念し、バックグラウンド処理を別のコアで効率的にさばけるようになりました。

また、メモリも4096MBに設定したことで、ヒープメモリ不足によるタスク落ちが激減し、安定した稼働を実現できました。特に、メモリを大量に使用するリクエストやバッチ処理を扱う場合、このスペックが最適でした。

### CPU使用率60%以上で1~10のタスクを増減
オートスケーリングの設定では、CPU使用率が60%を超えるとタスクを追加し、逆に60%を下回るとタスクを減らすルールを作りました。タスクの数は**1〜10の範囲**で動的に増減させています。

なぜこの設定にしたかというと、Fargate上のタスクが60%を超えるタイミングが一つの目安だったからです。60%を超えると、リクエスト処理が遅延し始める傾向があったため、あらかじめタスクを増やしてリクエストを分散することで、パフォーマンスを維持しています。

また、タスク数を10まで増やすことで、ピーク時の大量リクエストにも対応できるようにしました。逆に、タスクを1 で減らすことで、負荷が低いときにはコストを削減できるようにしました。この「**1〜10**」の範囲が、パフォーマンスとコストのバランスを取る最適な設定でした。

## まとめ
Fargateに移行して感じたことは、Lambdaと違ってリソース管理を自分でコントロールする必要があること。そして、Node.jsアプリにおいては、リソースを過剰に割り当てると逆効果になることがある点です。適切なタスクスペックを見つけ、オートスケーリングを上手に活用することで、効率的にリソースを使いながら、コストも抑えることができるようになりました。
応用情報技術者試験ノー勉で受けてみた

# はじめに

私は受かってないと思います（投稿時点では結果が出ていません）が、
受けてみてとても感銘を受けたので、ぜひエンジニアは受けてみてください。

何に感銘を受けたのかと言うと、「出題される問題がエンジニア職に必要だと感じる実践的な知識だった。」ということです。

後述しますが、私と同じくらいのスペックのエンジニアで応用情報資格を持っていない方は、ぜひ受けてみることをお勧めします。
また、3～5年目の若手エンジニアの方にもお勧めします。

あと毛色が全然違いますが、
試験当日アナログ時計は必ず持っていきましょう。会場に時計が無いことが多いようです。
私は忘れたので、体内時計で乗り切りました。

# 投稿主スペック

・福祉保育学校卒で、新卒で保育業界に就職後、突然エンジニアへ
・エンジニア歴10年（アプリ開発メインでフロント～バックエンドまで広く浅く）
・最近インフラにも興味があり、AWSの資格を取得

https://qiita.com/Jasmine_teeeeee/items/447256063ceae13c8e97

# 事前勉強

 2年前くらいに道場で何問か解いたが、二進数とか分数とかに必要性を感じず、中断。
 2024年度の試験前日と当日に去年度の解説を聞くだけ。

 これで勉強したって言うと怒られそうだけど、ノー勉も語弊があるかな..すみません。

# 出題される問題

## 公式

https://www.ipa.go.jp/shiken/kubun/ap.html

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778585/7e62c979-5ed4-f51e-22f1-6f8335d66589.png)
※公式引用

午前中は全部選択問題全80問で、
二進数の計算問題から、マネジメント手法まで幅広く出題されます。

### 過去問

公式が過去問と回答を公開してくれるのありがたいですね。

https://www.ipa.go.jp/shiken/mondai-kaiotu/2024r06.html#aki_ap

## 便利なサイト

以下サイトが詳しく記載してくれています。

https://www.ap-siken.com/aphani.html

こんな感じで、どんな分野の問題がどれくらいというわかりやすい情報を載せてくれています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778585/d4d98f4a-59b7-f8ed-bb7a-bdc88db8cbd5.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778585/d36ec739-779c-1515-194a-66f42d057d91.png)

※上記サイト引用

## どんな問題だった？

恐らく、私みたいにチャランポランタンに生きていない現役エンジニアの方であれば、
ノー勉で合格しちゃうんではないでしょうか。
それくらい実務で使う、または、日ごろの情報収集で獲得できる知識問題が出題されます。（所感）

あとは初見の知識がありますが、そこは過去問を解いて頂き、
新たな知識分野のとっかかりとなるので、それはそれで面白いと思います。

上記「便利なサイト」で見ていただくとわかりやすいかと思いますが、必要無い知識分野が存在しません。（基礎理論以外。とかいうと怒られそうなので、これくらいにして...）

これらの問題で出題される知識を基礎にすると、知識の獲得や業務がスムーズになると思います。
なので、若手エンジニアの方にもおすすめします。
（そもそも新卒の入社条件にあったりするのかな...）

# 終わりに

ほんとの勉強方法や受験方法とかもまとめた方がいいのかな。
このタイトルでクリックしてくださった方は、「ノー勉で合格する人はどれくらいのスペックホルダーなのか」の温度感を知りたい人だと思うので、とりあえずその情報だけ載せました。
画像処理エンジニア検定 エキスパート の勉強をするよ

こんにちは。

この記事は私が画像処理エンジニア検定の勉強を進める備忘録と、モチベーション維持のため作成される記事になります。
私は一応医療系の画像処理分野に従事していた経験があるので、フィルタ処理のGPGPUなどの経験があります。しかし、体系的に勉強をしたことがないので検定を受けることにしました。
それらの実践的な内容も踏まえて記述していきたいです。
記事中で使用する言語はRustを使用していきたいと思います。(GPUに対応するって宣言してるし期待してもいいよね？)

https://rust-gpu.github.io/

## 画像処理エンジニア検定とは？ 

公益財団法人画像情報教育振興協会(CG-ARTS)が行っている、画像処理分野の開発、設計に必要な知識の習得を評価する検定のこと。画像処理エンジニア検定の公式テキストの内容も面白いのでぜひ読んでみてほしいところです。

https://www.cgarts.or.jp/v1/kentei/about/img_engineer/index.html

ベーシックとエキスパートがあり、今回はエキスパートの内容を書いていこうと思います。

## 過去問さん

公式サイトで過去問も公開されています。こちらも使用していけたら嬉しいです。

https://www.cgarts.or.jp/v1/kentei/past/index.html

## 目次

[カメラの構成と幾何学モデルの話](https://qiita.com/Cy-San/items/aef6d2624168771aa932)
[カメラの撮影パラメータの話](https://qiita.com/Cy-San/items/2c415e15b844563ad8f7)

勉強しながら順次追加します。
GitHub Actions のワークフローを静的解析する actionlint を使ってみたよ

# はじめに

GitHub CI/CD実践ガイドにも紹介されている [actionlint](https://github.com/rhysd/actionlint) を実装して使ってみました。

https://gihyo.jp/book/2024/978-4-297-14173-8


# actionlintについて

actionlint は [ドッグ](https://x.com/linda_pp) さんという方が作った GitHub Actions のワークフローファイルを静的解析してくれるツールです。YAMLを書いているとあるあるな、しょーもないミスを早期検知してくれるものになります。

https://rhysd.hatenablog.com/entry/2021/07/11/214313


# 実装

- 弊チームでは、YAMLの拡張子は `.yml` で統一しているので `.yaml` は対象にしていません
- シェルチェックの一部を `SHELLCHECK_OPTS` キーワードで対象外にしています

```yaml:.github/workflows/actionlint.yml
name: actionlint

on:
  pull_request:
    paths: '.github/workflows/*.yml'
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  actionlint:
    runs-on: ubuntu-latest
    timeout-minutes: 5
    steps:
      - uses: actions/checkout@v4
        with:
          sparse-checkout: .github/workflows

      - name: Run actionlint
        env:
          SHELLCHECK_OPTS: --exclude=SC2129,SC2086 
        run: |
          bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash)
          ./actionlint -color
        shell: bash
```

- デフォルトでは Self-Hosted Runner のラベル名がバリデーションに引っ掛かるので、対象外にしています
- この設定ファイルは `$ actionlint -init-config` で生成できます

```yaml:.github/actionlint.yml
self-hosted-runner:
  # Labels of self-hosted runner in array of strings.
  labels: [label1, label2, label3]
# Configuration variables in array of strings defined in your repository or
# organization. `null` means disabling configuration variables check.
# Empty array means no configuration variable is allowed.
config-variables: null
```

# 使ってみて

- CI上で一瞬で静的解析してくれる（めっちゃはやい）
- `go` をインストールすればローカルでも実行可能なので、ミスの早期発見ができる（`ubuntu_latest` のタイポとか）
- ワークフローの実行を待たずとも早い段階でミスに気が付けるので、無駄な待ち時間が減った（今までは手動実行してエラーログ見てやっとミスに気が付いていたのでかなりありがたい）
- 既存のワークフローファイルにもフィードバックが返ってきたので、あんまりよくない書き方に気が付くことができた


# おわりに

総じてめっちゃ便利なのでおすすめです。繰り返すしょーもないミスにイライラしなくなる！はず！！
JenkinsジョブをAPIで実行する

# はじめに

地味に今まで使ったことなかったのでメモ。


# Jenkins version

- 2.387

https://www.jenkins.io/changelog-old/#v2.387


# step１．認証トークンの取得

1. Jenkinsのダッシュボードの右上にあるユーザー名をクリックし、「設定」を選択する
1. APIトークンから「トークンの新規追加」で認証トークンを生成する（後で使うので要メモ）


# step２．ジョブの設定内で「リモートからビルド」を有効にする

1. ジョブのサイドメニューにある「設定」を開く
1. 「ビルド・トリガ」セクションの「リモートからビルド」にチェックを入れる
1. 認証トークンの欄に作成したトークンの名前を入れる

![API実行のためのビルド・トリガ設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3388832/b5f93c72-10a5-a5aa-ad0d-6d11300d503c.png)


# Step３．リモートからエンドポイントを叩く

APIエンドポイントに含まれる `JOBNAME` はジョブへの実際のパスではないので注意です。

ジョブの設定の「ビルド・トリガ」セクションにチェックを入れると表示される注意書きみたいなところで確認できます。

> リモートからビルドを実行するには次のURLを使用します: JENKINS_URL/job/workspaces/job/api_test/job/job-without-parameters/build?token=TOKEN_NAME もしくは、 /buildWithParameters?token=TOKEN_NAME
Optionally append &cause=Cause+Text to provide text that will be included in the recorded build cause.

## パラメータがない場合

```bash: HTTP GETメソッドでもいけるけどPOSTが推奨されているっぽい？
curl -X POST -u ${USER_NAME}:${TOKEN} "JENKINS_URL/job/JOBNAME/build?token=${TOKEN_NAME}"
```


## パラメータがある場合

```bash: パラメータがシンプルな文字列の場合
curl -X POST -u ${USER_NAME}:${TOKEN} "JENKINS_URL/job/JOB_NAME/buildWithParameters?token=${TOKEN_NAME}" --data "FIRST_PARAM_NAME=${FIRST_PARAMETER}" --data "SECOND_PARAM_NAME=${SECOND_PARAMETER}"
```

他にも各種パラメータを使用できる。

- ファイルパラメータ（`@` 記号でファイルの絶対パスを指定）
- ブール値パラメータ（true / false を指定）
- 選択式パラメータ（ドロップダウンメニューの選択肢を指定）
- JSON形式を利用した複数パラメータ（JSON形式で一括で指定）

# 参考

https://www.jenkins.io/doc/book/using/remote-access-api/
DartError: Assertion failed: ...firebase_core_web.dart:283:11 options != nullを解決する

## 何をしたかったか
FlutterとFirebaseを同期させようとしたかったのですが、Firebaseの初期化がうまく行きませんでした。

## コード
```dart
void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(const MyApp());
}
```

## エラー文原文  
```console
DartError: Assertion failed: file:///Users/user-name/.pub-cache/hosted/pub.dev/firebase_core_web-2.18.1/lib/src/firebase_core_web.dart:283:11
options != null
"FirebaseOptions cannot be null when creating the default app."
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 296:3  throw_
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 29:3   assertFailed
packages/firebase_core_web/src/firebase_core_web.dart 283:18                 initializeApp
dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 45:50           <fn>
dart-sdk/lib/async/zone.dart 1661:54                                         runUnary
dart-sdk/lib/async/future_impl.dart 163:18                                   handleValue
dart-sdk/lib/async/future_impl.dart 847:44                                   handleValueCallback
dart-sdk/lib/async/future_impl.dart 876:13                                   _propagateToListeners
dart-sdk/lib/async/future_impl.dart 652:5                                    [_completeWithValue]
dart-sdk/lib/async/future.dart 532:22                                        <fn>
dart-sdk/lib/async/zone.dart 1661:54                                         runUnary
dart-sdk/lib/async/future_impl.dart 163:18                                   handleValue
dart-sdk/lib/async/future_impl.dart 847:44                                   handleValueCallback
dart-sdk/lib/async/future_impl.dart 876:13                                   _propagateToListeners
dart-sdk/lib/async/future_impl.dart 652:5                                    [_completeWithValue]
dart-sdk/lib/async/future_impl.dart 722:7                                    callback
dart-sdk/lib/async/schedule_microtask.dart 40:11                             _microtaskLoop
dart-sdk/lib/async/schedule_microtask.dart 49:5                              _startMicrotaskLoop
dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 181:7           <fn>
```

ポイントは、
>"FirebaseOptions cannot be null when creating the default app."

>options != null

の二箇所だと判断しました。

## 原因
Firebaseの初期化時に、オプションが指定されていませんでした。

## 改善案
初期化時に、任意のオプションを指定します。今回は、公式サイトの手順にありました"DefaultFirebaseOptions.currentPlatform"を使用しました。

## 改善コード
```dart
void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
  runApp(const MyApp());
}
```

これで、初期化に関する問題は解決しました。次の記述でも行えるそうです。

```dart
  await Firebase.initializeApp(
  options: FirebaseOptions(
      apiKey: apiKey, 
      appId: appId, 
      messagingSenderId: messagingSenderId, 
      projectId: projectId
    ))
```

## 参考文献
https://firebase.google.com/docs/flutter/setup?platform=ios

https://stackoverflow.com/questions/63492211/no-firebase-app-default-has-been-created-call-firebase-initializeapp-in
paizaラーニング問題集「【条件判定 2】視力検査」を解いてみた

https://paiza.jp/works/mondai/b_rank_new_level_up_problems/b_rank_new_level_up_problems__vision_test

▼考え方

ポイントになる考え方1.～2.を以下に示します。

1.テストの結果はすべて、辞書TJを用いて管理します。keyはテストの記号(TA,TB,TC,TD)で、valueはリスト形式です。valueの1要素目はテストの成功回数、2要素目はテストの失敗回数、3要素目はテストに合格ならば1とします。いずれの要素も初期値は0です。以下に例を示します。

例1）テストTAを初めて実施し結果が成功だった場合、以下のkey,valueをTJに追加します。
TJ["TA"] = [1,0,0]

例2）テストTAを初めて実施し結果が失敗だった場合、以下のkey,valueをTJに追加します。
TJ["TA"] = [0,1,0]

例3）2回目のテストTAに失敗した場合、すでに存在するkey:"TA"のvalueの2要素目を更新します。
TJ["TA"] = [<任意>,2,0]

例4）テストTAに2回失敗する前に2回成功した場合、すでに存在するkey:"TA"のvalueの1,3要素目を更新します。
TJ["TA"] = [2,<0or1>,1]

2.題意とおり、被験者の視力(A～E)を1行で出力します。辞書TJにテストの記号が存在しかつ合格していることが条件です。テストの記号が存在するかどうかはTA→TB→TC→TDの順番で検索します。条件に合致したら出力し検索を終了します。条件に合致しない場合は、題意よりEを出力します。

▼コード
```py
########## 処理0(準備) インプット,リスト定義 ###########

N = int(input())

# TJ: テストの結果を管理する辞書
TJ = {}

# TEST: テストの記号を格納したリスト。考え方2使用
TEST = ["TA","TB","TC","TD"]

########## 処理1 XXX ###########

# 考え方1.
for i in range(N):

    # t,j: 標準入力から渡されるテストの記号と結果を一時的に格納する変数
    t,j = input().split()
    
    if t not in TJ.keys():
        if j == "ok":
            TJ[t] = [1,0,0]
        else:
            TJ[t] = [0,1,0]
    else:
        if j == "ok":
            TJ[t][0] += 1
            if TJ[t][0] == 2 and TJ[t][1] < 2:
                TJ[t][2] = 1
        else:
            TJ[t][1] += 1

# 考え方2.
for i in range(len(TEST)):
    if (TEST[i] in TJ.keys()) and (TJ[TEST[i]][2] == 1):
        print(TEST[i][-1])
        break
else:
    print("E")
```
paizaラーニング問題集「【条件判定 1】郵便料金」を解いてみた

https://paiza.jp/works/mondai/b_rank_new_level_up_problems/b_rank_new_level_up_problems__posting_fee

▼考え方

題意の通りコードを書けば問題ないと思います。

1.縦と横の長い方の長さを判定するために、max(y,x)を使用しました。

2.縦と横と高さのうち最も長いものを判定するために、max(y,x,h)を使用しました。

▼コード
```py
########## 処理0(準備) インプット,リスト定義 ###########

y,x,h = map(int,input().split())

l_1,l_2,l_3,l_4,l_5 = map(int,input().split())

m_1,m_2,m_3,m_4,m_5,m_6 = map(int,input().split())

########## 処理1 郵便料金を求め、出力する処理 ###########

if h <= l_1:
    # 考え方1.
    if max(y,x) <= l_2:
        print(m_1)
    elif y+x <= l_3:
        print(m_2)
    else:
        print(m_3)
else:
    # 考え方2.
    if max(y,x,h) <= l_4:
        print(m_4)
    elif y+x+h <= l_5:
        print(m_5)
    else:
        print(y*x*h*m_6)
```
【rounded_loading_button】Error: No named parameter with the name 'onSurface'. の解決方法

# 環境情報

```zsh
❯ flutter --version
Flutter 3.24.3 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 2663184aa7 (5 weeks ago) • 2024-09-11 16:27:48 -0500
Engine • revision 36335019a8
Tools • Dart 3.5.3 • DevTools 2.37.3
```

```yaml
# pubspec.yml
dependencies:
  flutter:
    sdk: flutter
  rounded_loading_button: ^2.1.0
```

# エラーメッセージ

```zsh
Launching lib/main.dart on iPhone 16 Pro in debug mode...
Xcode build done.                                           18.2s
Failed to build iOS app
Error (Xcode): ../../../.pub-cache/hosted/pub.dev/rounded_loading_button-2.1.0/lib/rounded_loading_button.dart:197:11: Error: No named parameter with the name 'onSurface'.

Could not build the application for the simulator.
Error launching application on iPhone 16 Pro.

Exited (1).
```

# 解決方法

ライブラリのリポジトリのmasterブランチを指定する

```diff
# pubspec.yml
dependencies:
  flutter:
    sdk: flutter
- rounded_loading_button: ^2.1.0
+ rounded_loading_button:
+   git:
+     url: https://github.com/scopendo/flutter_rounded_loading_button.git
+     ref: master
```
AIベンダーの事情リンク2024/10版

# 備忘

オラクルは、ＲＤＢのサービスを三大クラウドに任せ、自身のクラウドはモデル生成用の環境に特化したいようです。

Azureが大量に用意した、HPCはOpen AIへ提供する為です。

AWSはブロードコムとハードウェア関連の取引が無い為か、VMwareのサービスができなくなりました。

Open AI への大規模な投資は、Azureへ還流されます。
結果、Open AIは対規模な投資を受け大きな売り上げを持った非上場企業となりました。
でも、会計的には大きな赤字を抱えてしまいました。

### OpenAI、AIインフラをAzureだけでなくOracle Cloudへも拡大へ

https://www.publickey1.jp/blog/24/openaiaiazureoracle_cloud.html

### オラクルクラウドのGPUインスタンス

https://www.oracle.com/jp/cloud/compute/gpu/

オラクルは大規模のGPUインスタンスを Open AI にのモデル生成に利用してもらうために用意した。
しかし、Open AI は実行環境に使うようです。

オラクルは、すでにデーターベースのサービスを三大クラウドで展開しています。
これだと労せずライセンス料だけ手に入れることができて効率が良いわけです。
自社のクラウドは、GPUといっしょに提供することに。

### 日本オラクルが新事業戦略、クラウド拡販とAI事業展開へ鍵握るパートナー支援の成否

https://xtech.nikkei.com/atcl/nxt/column/18/00001/08207/

### クラウド HPC の最先端：
未来を切り拓く スーパーコンピュータ
Microsoft Azure Eagle

### 数年ではなく、わずか数週間で発見: AI とハイパフォーマンス コンピューティング (HPC) が科学的発見をいかに加速するか

https://news.microsoft.com/ja-jp/features/240110-how-ai-and-hpc-are-speeding-up-scientific-discovery/

そんなに大量のＨＰＣ誰が使うねん、という答えは、Open AI だったようですね。

https://www.pccluster.org/ja/event/data/240627_pccc_wsSuzukakedai_27-11_matsumori.pdf

### NVIDIA GPUの覇権はいつまで続くのか、鍵握るブロードコムCEOの「転向」に注目

https://xtech.nikkei.com/atcl/nxt/column/18/00692/100100142/

### ブロードコムのVMware買収の影響がパブリッククラウドに波及、AWSに異変

米Amazon Web Services（アマゾン・ウェブ・サービス、AWS）が同サービスを新規に販売できなくなった。

https://xtech.nikkei.com/atcl/nxt/column/18/00001/09315


### 今さら聞けないブロードコムとVMware、基礎からライセンス問題まで5つの疑問

https://xtech.nikkei.com/atcl/nxt/column/18/02864/060600001/

余談なんですが、VMware買収の結果、オンプレミスとかAWSのVMが減り、AzureやGWSへのシフトが増えそうですね。
OCIのユーザー、グループ、ポリシーの確認

# はじめに
OCIのテナンシー内にあるユーザー、グループ、ポリシーの一覧を確認したので、そのメモです

https://docs.public.oneportal.content.oci.oraclecloud.com/ja-jp/iaas/Content/Security/Reference/iam_security_topic-Useful_CLI_Commands.htm

# ユーザーの一覧

今回は`ユーザー名`、`メールアドレス`、`最後にログインした日時`を抜き出しました

```
oci iam user list --all | jq -r '.data[] | {name: .name, email: .email, last_login_time: ."last-successful-login-time"}' 
```

# ポリシーの一覧

今回はポリシー名と設定しているポリシー構文を抜き出しました

```
oci iam policy list -c $C --all | jq -r '.data[] | {name: .name, statements: .statements}' 
```

# グループの一覧

今回は各グループに属するユーザーを確認したかったので、以下のようなShell Scriptを作りました

```groups.sh
#!/bin/bash

# テナンシーのOCIDを指定
TENANCY_OCID="ocid1.tenancy.oc1..xxxxxxxxxxxxxxxxxxx"

# テナンシー内の全てのグループをリスト
GROUP_LIST=$(oci iam group list --compartment-id ${TENANCY_OCID} --all | jq -r '.data[].id')

# 各グループに属するユーザーをリスト
for GROUP in ${GROUP_LIST}
do
    echo "Group: $(oci iam group get --group-id ${GROUP} | jq -r '.data.name')"
    USER_LIST=$(oci iam group list-users --group-id ${GROUP} | jq -r '.data[].id')
    for USER in ${USER_LIST}
    do
        echo "User,email: $(oci iam user get --user-id ${USER} | jq -r '[.data.name, .data.email]|@csv'| sed -e 's/\"//g')"
    done
    echo "-------------------"
done
```
Azure Portalのテナントの多要素認証の実施日を延期する

「対応が必要: 2024 年 10 月 15 日までにテナントの多要素認証を有効にする」とかメールが来て、「忘れてた！」「全アカウントのMFA対応したら...」「よくわからないので怖いから時間稼ぎしたい」という管理者のためのメモです。

## 前提

テナントの管理権限が必要です。お知らせメールが来ている人は権限を持っている人だとは思いますが。

## 対応方法

メールで指定された[多要素認証ページ](https://portal.azure.com/#view/Microsoft_Azure_Resources/MfaSettings.ReactView)にいっても「強制の延期」が押せません。

![スクリーンショット 2024-10-15 9.10.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14768/84452500-846c-cf53-9c13-c252e8dc4277.png)

以下の手順を行います。

- 「Home - EntraID」よりテナントの画面を開きます
- 「管理」->「プロパティ」を開きます
- Azureリソースのアクセス管理のトグルボタンを「はい」にして保存します
    ![スクリーンショット 2024-10-15 9.02.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14768/93b59d13-5a51-24e1-1228-0ca280b1bf80.png)

- [多要素認証ページ](https://portal.azure.com/#view/Microsoft_Azure_Resources/MfaSettings.ReactView)より「強制の延期」を押します

成功すると以下のようにロールアウトが延期されているのがわかります。

![スクリーンショット 2024-10-15 9.04.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14768/0b6b38f9-abd1-b824-ef46-bfe0164765af.png)

## けれども

半年猶予ができただけですのでその間にちゃんと対応しておきましょう。
機械学習における評価指標の基礎

## 目次

- [評価指標の概要](#評価指標の概要)
- [分類問題の指標](#分類問題の指標)
- [回帰問題の指標](#回帰問題の指標)
- [指標の選び方](#指標の選び方)

## **はじめに**
機械学習モデルを構築する際、その性能を適切に評価することは非常に重要です。モデルの精度が高いかどうかを測定し、どのモデルがより優れているのかを比較するためには、評価指標が欠かせません。

本記事では、分類問題や回帰問題で使用される主な評価指標の概要を説明します。

## **評価指標の概要**

機械学習における評価指標は、モデルの性能を定量的に評価するために重要な基準です。

これにより、モデルがどれほど正確に予測や分類を行っているかを判断でき、改善の方向性を明確にすることができます。

機械学習における評価指標は、分類、回帰などのタスクに応じて異なります。

例えば、分類タスクでは精度、適合率、再現率、F1スコアが一般的に使用されますが、回帰タスクでは平均絶対誤差（MAE）や平均二乗誤差（MSE）が用いられます。

これらの指標を理解し、適切に選択することが、モデルの性能を最大限に引き出すために不可欠です。

## **分類問題の指標**

- **正解率 (Accuracy)**： モデルが正しく予測したサンプルの割合。
```math
  \text{Accuracy} = \frac{TP + TN}{TP + TN + FP + FN}
```
     TP: 真陽性（正しく陽性と予測）
     TN: 真陰性（正しく陰性と予測）
     FP: 偽陽性（誤って陽性と予測）
     FN: 偽陰性（誤って陰性と予測）
- **適合率 (Precision)**： モデルが正と予測したサンプルのうち、実際に正である割合。
```math
 \text{Precision} = \frac{TP}{TP + FP}
```
    
- **再現率 (Recall)**： 実際に正であるサンプルのうち、モデルが正と予測した割合。
```math
 \text{Recall} = \frac{TP}{TP + FN}
``` 
    
- **F1スコア (F1 Score)**： 適合率と再現率の調和平均。**高い**ほど、モデルのバランスが良いと言える。

```math
F1 = 2 \times \frac{\text{Precision} \times \text{Recall}}{\text{Precision} + \text{Recall}}
```


## **回帰問題の指標**

- **平均絶対誤差 (MAE)**： 予測値と実際の値の絶対差の平均。**小さい**ほど、モデルの予測精度が高いことを示す。
```math
\text{MAE} = \frac{1}{n} \sum_{i=1}^{n} |y_i - \hat{y_i}|
```
- **平均二乗誤差 (MSE)**： 予測値と実際の値の差の二乗の平均。**外れ値の影響を受けにくい**特性がある。
```math
 \text{MSE} = \frac{1}{n} \sum_{i=1}^{n} (y_i - \hat{y_i})^2
```
- **RMSE**： MSEに平方根をつけたもの。
```math
\text{RMSE} = \sqrt{\text{MSE}}
```
- **決定係数 (R-squared, R^2)**： モデルがデータの分散をどれだけ説明しているかを示す指標。0から1の範囲で、**1に近い**ほどモデルの予測が実際のデータに適合していることを示す。異なるモデル間での選択を助ける重要な指標
```math
 R^2 = 1 - \frac{\sum_{i=1}^{n}(y_i - \hat{y_i})^2}{\sum_{i=1}^{n}(y_i - \bar{y})^2}
```

## 指標の選び方

機械学習のプロジェクトの目的に応じて、適切な評価指標を選ぶことが重要です。
例えば、分類問題では、精度だけでなく、適合率や再現率、F1スコアを考慮し、クラス不均衡を補正する必要があります。
また、ビジネスや医療のような現場では、偽陽性や偽陰性がどのように影響を与えるかを十分に考慮して評価指標を選ぶことが求められます。

### クラス不均衡への対応

クラス不均衡の影響を減らすために、適合率や再現率、F1スコアを併用することが推奨されます。特定のクラスに偏ったデータでは、正解率だけでなく他の指標を併用することで、モデルの性能を正確に評価できます。

## まとめ

機械学習モデルの評価には、タスクの目的に応じた適切な評価指標を選ぶことが重要です。分類問題では、精度だけでなく、適合率（Precision）、再現率（Recall）、F1スコアなどを併用して、モデルの強みと弱みをバランス良く評価することが求められます。

回帰問題では、平均絶対誤差（MAE）や平均二乗誤差（MSE）、決定係数（R^2）などを使用し、モデルの予測精度を評価します。外れ値の影響を考慮した指標も活用すると良いでしょう。

プロジェクトの目的やデータの特性を十分に理解し、複数の指標を組み合わせることで、モデルの総合的な性能を適切に評価することが、機械学習の成功に繋がります。
【PowerApps】SharePointリストの画像列に画像を一括保存

## 【PowerApps】スマホで連続撮影して、SharePointリストに一括保存 その２

<iframe width="560" height="400" src="https://www.youtube.com/embed/uHCy1MzAXpw?si=FOuRLXoeEBYLf3b0" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

↑動画でも解説しています。

コレクションのcol_imageは_image列に画像、_save列に選択の有無
SharePointリストのimage_listは画像列image_gazouに画像を保存します。

保存するボタンに以下の数式を入力
```
ForAll(
    Filter(
        col_image,
        _save = true
    ),
    Collect(
        image_list,
        {image_gazou: {Value: _image}}
    )
)
```
分解してみていきます。

初めのForAll関数はデータを順に取出し、数式を処理していく関数です。
```
ForAll(データ,数式)
```
の形で記入します。
今回は、データにフィルターをかけたコレクションのcol_image。
数式にはSharePointリストのimage_listに保存する数式を入れています。
```
 Filter(
        col_image,
        _save = true
 )
```
データのコレクションはFilter関数で＿save列がtrueのものだけに絞り込んでいます。
ギャラリーでチェックを入れた列だけ保存する想定です。
コレクションの中身をすべて保存するなら、フィルター掛けずにcol_imageだけでOK。
```
 Collect(
        image_list,
        {image_gazou: {Value: _image}}
 )
```
こちらが、Collect関数でSharePointリストに画像を保存する部分。
image_listの画像列image_gazouに{Value:画像}を入れます。
_imageはコレクションの_image列の画像ですが
ForAll関数でコレクションの行を順に処理していくので、保存する画像が順次ここに入ります。
React Router初心者向け：Navigateのtoとreplaceの違いをシンプルに解説

React Routerで使用するNavigateコンポーネントの`to`と`replace`の使い分けを初心者向けに説明します。React Routerは、SPA（シングルページアプリケーション）でルーティングを管理するためのライブラリです。

## 1. `Navigate to` とは
`Navigate`コンポーネントの`to`プロパティを使うと、指定したURLに遷移します。たとえば、ログイン後にユーザーをホームページにリダイレクトしたいときなどに使います。

```jsx
import { Navigate } from "react-router-dom";

function Example() {
  return <Navigate to="/home" />;
}
```
この例では、`/home`に自動的に遷移します。

##### 使いどころ
ユーザーがある条件を満たしたとき（例えば、ログインが成功した場合）に自動的にページ遷移させる場合に使います。

## 2. `Navgate replace` とは

`replace`プロパティを使うことで、遷移先のページが**履歴に残らない**ように設定できます。ブラウザの「戻る」ボタンを押したとき、通常は前のページに戻りますが、`replace`を使うと、現在のページの履歴を**上書き**するため、戻るボタンで戻れなくなります。

```jsx
import { Navigate } from "react-router-dom";

function Example() {
  return <Navigate to="/home" replace />;
}
```
この例では、`/home`に遷移する際に、`replace`を使うため、現在のページの履歴を上書きします。
##### 使いどころ
例えば、ログイン後のリダイレクト時などで「戻る」ボタンでログインページに戻らせたくない場合などに使います。セキュリティやユーザー体験を向上させるために、意図的に「戻る」を無効化する場合に便利です。

## 3. `Navigate` コンポーネントの他のプロパティ
`Navigate`には他にもいくつかプロパティがありますが、初心者にとって覚えておくと便利なものは以下の2つです。

**state**：`state`プロパティを使って、遷移先のコンポーネントにデータを渡すことができます。URLのクエリパラメータとは異なり、URLに表示されません。
```jsx
import { Navigate } from "react-router-dom";

function Example() {
  return <Navigate to="/home" state={{ from: "login" }} />;
}
```
**replace**：上で説明した通り、履歴を上書きするために使います。戻るボタンで元のページに戻させたくない場合に便利です。

## まとめ
**Navigate to="/path"**：指定したURLに遷移します。通常のページリダイレクトに使用。
**Navigate to="/path" replace**：履歴を上書きし、戻るボタンで元のページに戻らせたくないときに使用。
**state**：遷移先にデータを渡すことができ、これはURLに表示されません。
Rails - rails console ( pry )で配列テキストが省略表示されてしまいコピー&ペーストしづらいので、ページングを無効にする

# 問題

rails console ( pry ) で配列の列が長くなると、続きが省略されて、ページングされてしまう。

スクロールしないと続きが見られないし、コピー&ペーストもしづらい。


例

```
pry(main)> [*1..10000]
```

<img width="562" alt="image" src="https://github.com/user-attachments/assets/14dc63f3-903f-4248-8c7c-40f0a0b7dd69">



# 前提


まずは `Gemfile` で `pry-rails` を入れておく

```
gem 'pry-rails'
```

インストールしておく

```
$ bundle install
```

# 解決

pryの設定でページングを無効にする

```
vi .pryrc
```

```
Pry.config.pager = false
```

結果の例

```
pry(main)> [*1..10000]
```

<img width="1218" alt="image" src="https://github.com/user-attachments/assets/83d37028-9abe-493b-be48-1e81fdc6bcf8">

# 別問題 ( ActiveRecord の配列 ) の解決

ActiveRercord のインスタンスが多い配列だと

```
User.all
```

次のように省略表示されてしまう場合がある

```
[#<User id: 1>,
 #<User id: 2,>,
 #<User id: 3,>,
 "..."]
```

この場合は てきとうに each すると全て表示できた

```
User.all.each { }
```



# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# プロフィール・経歴

https://github.com/YumaInaura/YumaInaura
Python リスト内包表記とは

## 問題の発生
いままで、「リストの内包表記って結局、forやらifが続いているコードをちぢめただけでしょ？学ぶのはあとでいいや」と敬遠してきた。しかし、プログラミングやpythonの学習で自作のプログラムを組んでいくと、コードがだらだらと長くなってしまい、あとから見返すと自分ですらわかりにくいことがあった。そこで、もっと簡潔にわかりやすく書きたいと感じるようになったので学習してみることにした。

## 基本的な形
### for文でリストに格納する
```python
my_list = [変数 for 変数 in 繰り返すもの]
```
例）
```python
my_list = [i for i in range(5)]
print(list)

#結果
#[0, 1, 2, 3, 4]
```

### forとif
条件に一致するものだけリストに格納される
```python
my_list = [変数 for 変数 in 繰り返すもの if 条件]
```
例）
```python
my_list = [i for i in range(5) if i % 2 == 0  ]
print(my_list)
#結果
#[0, 2, 4]
```

### 三項演算子
三項演算子の結果の値がリストに格納される
```python
my_list = [Trueのときの動作 if 条件（変数に対して） else Falseのときの動作 for 変数 in 繰り返す処理]
```
```python
my_list = ['偶数 ' if i % 2 == 0 else i for i in range(5)]
print(my_list)
#結果
#['偶数 ', 1, '偶数 ', 3, '偶数 ']
```

### ifの違い
:::note
ifがforの後に来ると条件に一致するものがリストに追加される。
ifがforの前に来ると条件に基づいて要素の値が変更され追加される。
:::

## 注意点
リスト内包表記はリストを新規作成することに適しているため、既存のリストに追加する場合には append や extend を使う。リスト内包表記で直接 append や extend を使うことはできない。


## 感想
リスト内包表記を使うことで、コードが短く、かつ読みやすくなると感じた。ただし、複雑な処理を詰め込みすぎると逆にわかりにくくなるので、使いすぎには注意が必要。
Entity Framework CoreのマイグレーションがWindows SDKバージョン指定プロジェクトでエラーになる問題の解決方法

# 概要

Entity Framework Coreを使う場合に、Windows向けのプロジェクトでマイグレーションがエラーになるという問題にぶつかったので、その解決方法です。

# 解決方法

プロジェクトのターゲットに、次のようにWindowsSDKのバージョン指定が入っている場合に発生します。

```xml
<TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
```

解決方法としては、いったん次のようにWindowsSDK指定を外して実行した後、また元に戻せばOKです。

```xml
<TargetFramework>net8.0</TargetFramework>
```

理由ははっきりしないのですが、エラー内容が次のようになっているため、指定されたバージョンのWindowsSDKのDLLを探しに行き、該当のものが無いためにエラーになっているように見えます。

```xml
Error:
An assembly specified in the application dependencies manifest (ProjectName.deps.json) was not found:
package: 'runtimepack.Microsoft.Windows.SDK.NET.Ref', version: '10.0.19041.31'
path: 'Microsoft.Windows.SDK.NET.dll'
```

[同じような問題に .NET 6で引っかかっているスレッド](https://stackoverflow.com/questions/72859258/net-6-project-builds-successfully-but-wont-build-during-any-dotnet-ef-comman)も見かけたので、EF Coreの仕様なのかもしれません。

ごく普通のWindowsSDK指定のプロジェクトで使っていきなりエラーになるというのも困ったものですが・・・知っていれば回避することは簡単なので、面倒ですが運用で何とかするしかなさそうです。
Entity Framework Coreで、同じプロジェクトに複数のDBContextを入れる場合のマイグレーションの使い分け方

# 概要

Entity Framework CoreのCode Firstでは、DBContextを継承した型でDBのテーブルを定義すると、コマンドでDBのマイグレーションをしたりそのためのSQL文を出力できます。しかし、1つのプロジェクトで複数のDBを扱いたい場合は、複数のDBContext派生型を作って同じコマンドを打っても、マイグレーションが上手く行きません。その場合のマイグレーションのやり方です。

# 解決方法

次のように、通常のマイグレーションのコマンドに、2つのオプションを追加します。

```powershell
dotnet ef migrations add <このマイグレーションの名前> --context <DBContext派生型のクラス名> --output-dir <このマイグレーションの出力先フォルダパス>
```

contextオプションに、どのDBContext派生型のマイグレーションを追加するかを指定します。ここはクラス名をそのまま指定します。

そのままだと別々のDBContext派生型のマイグレーション出力が混ざって分かりづらくなるため、output-dirオプションに、出力先のフォルダを指定します。DBContext派生型ごとにフォルダを分けると良いと思います。

値を入れた例としてはこんな感じです。

```csharp
//前提
class UserDBContext : DBContext { ... }
class RoleDBContext : DBContext { ... }
```

```powershell
dotnet ef migrations add Ver_2_0 --context UserDBContext --output-dir Migrations/UserDB
dotnet ef migrations add Ver_2_0 --context RoleDBContext --output-dir Migrations/RoleDB
```

この後のupdateコマンドなども同様に、contextオプションを指定します。

```powershell
dotnet ef database update --context <DBContext派生型のクラス名>
```

値を入れた例だとこうなります。

```powershell
dotnet ef database update --context UserDBContext
dotnet ef database update --context RoleDBContext
```

EF Coreはサンプル通りに動かすだけならサンプルのコマンドをコピペするだけでも動きますが、ちゃんと使っていくと理解するべきところが増えてきます。1つずつ調べていきましょう。
[AWS #26] Amazon MemoryDB for Redis / Neptune

<!--
 <font color="c00000"></font> 赤
-->
## はじめに
こんにちは
今回はデータベースサービス分野である **<font color="c00000">「Amazon MemoryDB for Redis」「AWS Neptune」</font>** について紹介したいと思います。
:rolling_eyes: 「Neptune」→ 海王星？ ローマ神話の神様？　ん～？

## Amazon MemoryDB for Redis
:upside_down: **Amazon MemoryDB for Redis** とは、インメモリデータベースサービスで、redisと<font color="c00000">**互換性**</font>があります。Redisを耐久性のあるプライマリデータベースとして使いたい場合はこのMemoryDB for Redisを使用します。

:::note info
Redisを耐久性のある<font color="c00000">**プライマリデータベースとして使いたい**</font>場合はMemoryDB for Redisを使用します
:::
## Amazon Neptune
:upside_down: Amazon Neputuneは、フルマネージドの<font color="c00000">**グラフデータベース**</font>です。
**関係性や相関情報**を扱います。SNS、レコメンデーション（提案）エンジン、経路案内、物流最適化などのアプリケーション機能に使用されます
![AWS26_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806875/d6955a35-8bbc-ca50-467f-3e9a4850459c.png)

Neptuneでは、**ノード**、**エッジ**、**プロパティ**などのグラフ構造を使用して、データを表現及び保存します
・ノード → 頂点(Vertex)とも言います
・エッジ → 辺(Edge)とも言います
・ラベル → ノードやエッジの種類です
・プロパティ → ノードやエッジに紐づけられる属性情報です、複数登録可能

:::note info
**Neptune**は<font color="c00000">**複雑な関係性を扱うグラフデータベース**</font>です
:::

## おわりに
今回のちょっとしたまとめになります。

:::note info
データ同士の<font color="c00000">**複雑な関係性を表現**</font>するのに適している、便利である
:::


最後までお読みいただきありがとうございました！
>>日頃より活用している参考書です。
>> **「参考書」**
[AWS認定クラウドプラクティショナー改定第3版（ACMは237ページ）](https://x.gd/19i6N)
>
> **「AWS公式サイト」**
[Amazon MemoryDB for Redis](https://aws.amazon.com/jp/memorydb/)
[Neptune](https://aws.amazon.com/jp/neptune/)
>
【資格】非ITの事業会社エンジニアがAWS認定資格を取る意味

# 1. みんな大好き資格のお話
皆さん、AWS認定資格取ってますか？
私はAIプラクティショナー（24年10月時点 β版）をチャレンジして見事不合格となりました:tired_face: 

まあ、これも経験です！

クラウド技術は日々進化し、AWSの資格はエンジニアにとって非常に重要で、今や持っていて「当たり前」とも言える辛い存在になってきています。


ITが本業ではない事業会社のエンジニアにとって、その「当たり前」なAWS認定資格の取得にどんな意味を持つのか、どう向き合っていけばいいのでしょうか？

本記事では、資格の重要性や取得するメリットについて、私の考えを整理してみます。

# 2. 事業会社エンジニアのAWS認定資格取得とその先
AWS認定資格を取得することは、自社システムの最適化やキャリアアップに繋がる大きな一歩です。しかし、資格を取得しただけでは全ての課題を解決できるわけではありません。重要なのは、資格で得た知識を自組織の業務にどう活かしていくかを考え、組み替えながら実践を通じて技術力をさらに高めることです。


以下では、事業会社のエンジニアにとってAWS資格がどのようなメリットを整理してみます。

## 2.1 事業成長を支える技術力の向上
AWS認定資格は、事業成長を支えるための技術力向上に繋がると言えます。例えば、資格取得を通じて得た知識を活かし、システムを自社で設計・構築する力を養うことができます。

もちろん、すべてを自社でやり抜く必要はありませんが、ベンダーに依頼する場合でも、設計の意図やAWSの使い方をしっかり理解しているのと、理解していない(腹落ちができていない)のでは、事業に合った柔軟なシステム運用の実現度という意味では大きな差があると考えています。

また、AWSのベストプラクティスを単純に適用するのではなく（ただ、諸事情で出来ない場合が多い）、自組織においてどうあるべきかを考え、必要に応じてカスタマイズすることで、より実践的で効果的な技術力が身につくと私は考えています。

| 技術力向上 | ポイント |
|:--|:--|
| 最新技術の導入で競争力を強化 | 新しい技術を積極的に導入し、競争力を高める |
| 柔軟なシステム設計 | AWSを活用して、事業の変化に対応可能なシステム設計を実現 |

## 2.2 システム最適化への貢献
AWS認定資格で得られる知識は、システムの最適化にも役立ちます。
ただし、システム最適化は資格があるからといってスムーズに進められるほど簡単なものではありません。しかし資格で得た知識を活用し実践を重ねることで、システムのアーキテクチャを最適化し、コスト削減にも繋げることが可能です。

基幹システムをAWSへリフトしたままオンプレ思想で塩漬け状態にしておかず、オートスケーリングやサーバーレス技術など部分的にクラウド特有の機能を採用し、少しずつクラウドらしい使い方へシフトしていくのもシステム最適化の１つのアプローチだと考えています。

| システム最適化 | ポイント |
|:--|:--|
| リソースの効率的な利用とコスト削減 | オートスケーリングを活用し、ピーク時のみリソースを拡張することで、平常時のコストを削減 |
| パフォーマンスと柔軟性の向上 | サーバーレス技術や適切なAWSサービスを利用し、システムのパフォーマンスを向上させ、事業のニーズに応じた柔軟な運用が可能 |

## 2.3 社内での評価向上とキャリアアップ
資格を取ることは、技術力を証明するだけでなく、キャリアアップの大きなチャンスにも繋がります。新しいプロジェクトに声をかけてもらえたり、リーダーシップを発揮する場面が増えることもあります。また、資格で得た知識をチーム内で共有すれば、チーム全体のスキルアップにも貢献でき、それが自身の評価向上にも直結します。

資格はあくまで成長の「きっかけ」ですが、知識を業務で活かすことで、具体的な成果を生み出し、キャリアを次のステージへと引き上げることができます。


| 社内評価/キャリアアップ | ポイント |
|:--|:--|
| 技術力の証明 | 資格で技術力を証明し、社内外での評価を向上 |
| プロジェクト参画の機会増加 | 新たなプロジェクトや重要な役割に参加する機会が増える |
| リーダーシップの強化 | 技術力を証明し、リーダーシップを取る機会が増える |
| チーム力向上 | 資格で得た知識を共有し、チーム全体のスキルアップに貢献 |
| 継続的な学習 | 資格取得後も学び続けることで、長期的なキャリアアップ |

# 3. SIerと事業会社における資格取得のモチベーションの違い

AWS認定資格を取得する理由は、SIerと事業会社のエンジニアで異なることがよくあります。資格取得の背景や目的を見つめ直し、どんな価値があるかを考えることが重要です。

以下は私の理解で目的の一例です。

| 立場 | 取る目的 |
| --- | --- |
| **SIer** | - 顧客に技術力を示し、信頼を得る<br> - プロジェクト提案や営業活動で強みを発揮し、競争力を高める<br> - 転職 <br> - 奨励金  |
| **事業会社** | - 自社システムの効率化や運用コストの削減<br> - システムの柔軟性を高め、ビジネスの成長を支える<br> - 転職 |



資格取得の目的はそれぞれ異なりますが、自分にとっての目的を整理し、その後を見据えることが大切と考えています。

# 4. まとめ
AWS認定資格を取得することは、事業会社のエンジニアにとっても大きな意味があります。自社システムの効率的な運用やコスト削減、新しいチャンスをつかむきっかけとなるだけでなく、ビジネスのニーズに応じた柔軟なシステム設計を実現し、チーム全体のスキルアップや会社の競争力向上にも貢献できます。

資格は「個人のスキルアップ」を超え、さらなる成長を促し、組織全体に良い影響を与える力を持っていると私は考えています。

AWSに限らず資格取得を目指している方や、これから挑戦しようと考えている方にとって、この記事が一つの考え方として役立てば幸いです。

# 弊社では一緒に働く仲間を募集中です
現在、様々な職種を募集しております。
カジュアル面談も可能ですので、ご興味のある方は是非ご連絡ください！

募集内容等詳細は、是非採用サイトをご確認ください。
https://engineer.po-holdings.co.jp/
ポモドーロタイマーを作成しました

今まで使っていたios版ポモドーロタイマーに不満があったので自分で作ってみました。
下のzipファイルを解凍してご使用ください。m(_ _"m)

ポモドーロテクニックを使って素敵な勉強ライフを！🍅


https://github.com/shouzou-nozaki/PomodoroTimer/tree/main/app
AmazonLinux2023にfail2banを導入する

# はじめに
AWSでEC2をベースに何かしらのWebサイトを立ち上げ、
DDoS攻撃を対応しようと考えた場合、
基本的にはAWS WAFを導入して対策しよう、と考えるのが適切かと思いますが、
その為にはApplication Load Balancerを導入する必要があり、
小規模でモノリシックな環境で十分、と考えるケースにおいては
コスト的には不釣り合いで、導入を見送るという事もあるかと思います。

そんな状況において、RHELベースのOSを利用していたのであれば、
<b>fail2ban</b>を選択肢に入れる事は大いに考え得る事ですが、
OSにAmazonLinux2023を選択した場合、従来通りの手法ではインストールが難しいので、
本記事ではそこに焦点を当てて行きます。

# 何故fail2banを導入する事が難しいか
## AmazonLinux2023のyumリポジトリ内に無い
al2023のデフォルト状態から、dnfによるfail2banのインストールは出来ません。
理由は単純で、al2023のyumリポジトリ内に存在していない為です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737208/6163abb2-569f-dc85-6856-4eb7508c50bd.png)

## AmazonLinux2023にはEPELが導入出来ない
RHELベースのOSを利用していて、かつてfail2banを導入して来た人にとって、
考え得るインストール手順は<b>EPELリポジトリ</b>を導入する事だと思います。

筆者もその内の一人で、同じ様にAmazonLinux2023でEPELを導入しようと思いましたが、
AmazonLinux2023ではEPELをサポートしておらず、この手法を使う事は出来ません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737208/1466b74b-4558-21a7-29c1-3fda8672aab9.png)


# インストール手順
fail2banをインストールをする為には、直接buildを行います。
インストールするパッケージは、githubから取得します。

### python3-develの導入
まず、python3-develをインストールします。インストール済なら本作業は不要です。

```
sudo dnf install python3-devel
```

### 作業用ディレクトリに展開
作業用ディレクトリ/tmpにwgetでパッケージを取得し、tarで展開します。
作業する場所はホームディレクトリでも構いません。

```
cd /tmp/
wget https://github.com/fail2ban/fail2ban/archive/refs/tags/1.1.0.tar.gz
tar -xzvf 1.1.0.tar.gz
```

### fail2banサービスの作成
fail2banのインストールと、サービスの作成を行います。

```
cd fail2ban-1.1.0/
sudo python3 setup.py build
sudo python3 setup.py install
sudo cp ./build/fail2ban.service /etc/systemd/system/fail2ban.service
```

このままサービスを起動したくなりますが、その場合エラーが発生して起動しません。
正常に起動する様に修正する為、fail2banサービスの設定ファイルの修正を行います。

<details><summary>起動に失敗した画像サンプル</summary>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737208/14144046-4d77-5bb3-00d2-e734297e10f4.png)

</details>

### サービス設定ファイルの変更
コピーして作成した、/etc/systemd/system/fail2ban.service の修正を行います。
以下のEnvironmentの箇所です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737208/fdf7e8ef-c334-d1bc-e009-dbe64373b519.png)

ここに先程インストールした、python3-develを指定します。
具体的には、以下の様に書き換えます。

```
Environment="/usr/local/lib/python3.9/site-packages"
```

### サービスの再起動／自動起動有効
最後に、サービスを再起動し、自動起動も有効にしておきます。
systemctl statusにて、正常に起動しているかどうかも確認します。

```
sudo systemctl restart fail2ban
sudo systemctl enable fail2ban
```

<details><summary>起動に成功した画像サンプル</summary>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737208/f33ce225-ff33-7441-e165-b3295c96d266.png)

</details>

# コマンド一覧
お急ぎの方はこちらからどうぞ。
```
# python3-develの導入
sudo dnf install python3-devel

# 作業用ディレクトリにて展開
cd /tmp/
wget https://github.com/fail2ban/fail2ban/archive/refs/tags/1.1.0.tar.gz
tar -xzvf 1.1.0.tar.gz

# fail2ban serviceの作成
cd fail2ban-1.1.0/
sudo python3 setup.py build
sudo python3 setup.py install
sudo cp ./build/fail2ban.service /etc/systemd/system/fail2ban.service

# サービス設定ファイルの変更
sudo sed -i '/PYTHONNOUSERSITE/a Environment="PYTHONPATH=/usr/local/lib/python3.9/site-packages"' /etc/systemd/system/fail2ban.service

# サービスの起動
sudo systemctl restart fail2ban
sudo systemctl enable fail2ban
```
(SSD1306)「こんにちは...」を表示して遊ぶ。(M5NanoC6)(M5UnitGLASS2)(M5Unified)

(SSD1306)「こんにちは...」を表示して遊ぶ。(M5NanoC6)(M5UnitGLASS2)(M5Unified)


x 過去ログを見よ!!
x M5Unifiedのインストール
x M5UnitGLASS2のインストール
x M5Unified 0.2.3
x M5GFX 0.2.5
x ESP32 3.0.7
x UNIT_GLASS 0.0.1



参考

![o_coq516.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/d987bd6f-98a1-f51a-e562-e185db3432e9.jpeg)


https://akizukidenshi.com/catalog/g/g112031/


https://qiita.com/nobrin/items/779de0aed84cec8885d9




https://qiita.com/caa45040/items/88ce7ee0006fdbe425e0


https://qiita.com/caa45040/items/2ed51f2c942945a075e1




目的

SSD1306のらびあん様系のツール系を
@nodrin様の記事を元にArduino IDEで実験してみました。


結果

![o_coq512.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/9f1812c1-21ac-46a9-a5e0-a1c060a9f1ed.jpeg)



プログラム


```c++

#include <M5UnitGLASS2.h>
#include <M5Unified.h>

// Port.A SDA(G2), SCL(G1)
M5UnitGLASS2 SSD1306Display(2, 1);

void setup() {
  M5.begin();
  SSD1306Display.init();
  SSD1306Display.setFont(&fonts::lgfxJapanGothicP_16);
  SSD1306Display.println("こんにちは世界!!");
  SSD1306Display.setFont(&fonts::FreeMonoBold9pt7b);
  SSD1306Display.println("SSD1306\nGME12864-51");
}

void loop() {
}



```
やる気が出た時の記録_0

```
やる気が起きた時、
その直前の行動は何をしていたのか？
それを記録することで、
自分のやる気の出る、
タイミングや条件が
見つかるかもしれない。

やる気が起きたときの行動記録。
```
(新しい日付順)
---
## 2024-12-23
６時間ぶっ通しで作業してる今。
アイドルさんと直接お会いして遊べたからです。
https://www.youtube.com/live/ABbMEhEtof0?si=F56hulqt3ddjHzcT
初めてのことです。アイドルに執着することは。
３年間ずっとこのメンバーの音楽を聞いていたからですね。
がんばります。

案内してくれるのが嬉しい！推しです！と伝えると、
「おいでおいで」をしてくれて、嬉しくて嬉しくて泣きそう！それくらい。
SO.ON project LaV さんたちはITをたくさん取り入れてこの世界に取り組んでいる姿が、自分の目指す場所なので、憧れなのです。
私にはかなり大きい存在だったみたいです。執着している理由が今日わかりました。頑張って、そこに、自分も行こう。


## 2024-12-20
嫉妬。
https://www.youtube.com/watch?v=AiV8OF9bc28&list=PLyGjs39YnmCNmJybhH_dm34VHtcmAapiy&index=4
悔しい。悲しい。私の無力さ。まずはココを目指す…。このひとの目標が私と少し似ている。
しかし私はこの人の上の目標である、「人を助ける」という形が絡んでいる。
悔しい、、なんで、、、助けて、だれか、、同盟組みませんか、、

もし、未来、上にイケたなら。
自分はココから落ちたくない！！という思いで頑張ることができる。高校の時そうだった。



## 2024-11-11
少しやる気が続いているので記録する。
- ### 「やる気」は存在しない
  というお言葉を、なんかVRCHATでNAGISAで出会った人から頂いた。
  なので、「やる気」ではなく、
  ### 「やる気がなくても取り掛かれる力｣
  として考えを進めてみた。
  試行錯誤結果、
  ### ダラダラやっても良いので、アニメを見ながら作業をやり始めた。
  → これで一応、取り掛かることが出来たことになる。
  ### 確かに効果はあり、
  作業は実際少しながらも進んだ。
  
さらに、次のことを2週間前程から上記の "アニメを観ながら作業をする方法"に加え、以下のやり方をさらに組み込んだ。

- ### タイマーを首からぶら下げた。
  作業中に「辛い」と感じた時に「1分」だけ計り、
  1分間辛いながらも作業を続けることをした。
  1週間後に3分、2週間後に5分と伸ばした。(その日その日で辛ければ1分にしたり、調節した。)

その結果、この2つを同時に行っていると、
```
アニメが鬱陶しいと感じ、
アニメを一時停止して
作業のみに手を付ける
…という行動を
身体が勝手に欲しがるという現象
```
この現象が時々発生した。この現象時には素直に
### アニメを、10秒とか、30秒とか、一時停止して、
ちょっと気が済むまで作業を進めた。
  
このまま続けてみよう。
確かに少しながら、作業効率は良くなっている。
むしろ作業を少しでも進めることが出来ている現在の環境は成功している気がする。
  
## 2024-10-15
- ご飯をたくさん食べた（材料：[ナス, 豚肉, 舞茸, 醤油, 白ワイン, 砂糖, 昆布だし, あごだし]、調理：[電気圧力鍋 50分]）
- 食後、3時間ほど寝た
- エナジードリンクを飲んだ（ZONE FRUITS MIX BOOST + GRAPE）
- 作業内容を見直して少し進めた。デバッグの部分が少し分かりやすくなって、手をつけやすくなった。

## 2024-12-09
辛い時に５分タイマー、まだ続いています。素晴らしいです。
続いてると言うか、今できる時にやっているので続いています。
なんか、、ゲーム実況をひたすらループしながら作業してるのが最近良い、
フロントエンジニアになるために～1日目～

# 2024年10月15日初記載

## **目標**
**1年以内（2025年9月まで）にフロントエンジニアとして副業でもいいので案件獲得**
サブ目標として習慣化意識して目標達成

## 現状
新卒の2020年4月からSEとして働いている。
現在28歳

●**経験してきたこと**
　└Winactor（2年半）
　└VBA（2年半）
　└Tableau（半年）
　└Informatica PowerCenter（1年）
　└MySQL（半年）
　└PowerAutomate（3か月）
　2024年7月 WinActorエキスパート試験　合格

## なぜこの記事を作成したか
主にDX関連の業務に携わることが多かった。
業務効率化の仕事にもやりがいは感じるが、このまま同じことを続けるより新たな知識（Web系の知識）も身に着けたいと考えた。
さぼり癖、報連相が苦手な私が記事を作成することで、習慣化を意識して目標を達成することを目指す。

## 1日目の内容
まずは目標設定、現状の把握、記事作成の理由を記載。（朝4時記載）

下記の記事を参考にまずはWebフロントエンジニアのリサーチを実施
リサーチを実施するにあたり、自分がエンジニアとして用語を知らなすぎることに気づき、まずはエンジニアとして知らない単語を調べ、ここにアウトプットする。

https://qiita.com/nemutas/items/eeb3887e9bcf5338fdd0#%E6%A6%82%E8%A6%81
### アウトプット

**静的型付け言語**
>C言語やJava、TypeScriptが静的型付け言語
>型が実行時よりも前のコンパイル時で定まるというのが、静的型付け言語の特徴

**動的型付け言語**
>RubyやPython、PHP、JavaScriptが動的型付け言語
>変数の型はプログラムを実行するまで定まらないのが特徴
>実行するまで型の問題は見過ごされる

**コンパイル**
>指定された言語で書かれたコンピュータープログラムを、別の形式や言語の一連の命令に変換する作業

**TypeScript**
>JavaScriptに型をつけた静的型付け言語と呼ばれ、開発中にエラーを出してくれるため安全に開発することができる

**jQuery**
>JavaScriptを簡単に記述できるように作られたライブラリ。
>Web制作会社ではよく使われているが、モダンなWeb企業では使われない。
>JavaScriptのコードを簡潔に書くことを目的に開発されたライブラリ
>具体的には**表示されているページをより使いやすくすること**

10/15の学習は以上
10/16へ
2024/10/15主にITとかセキュリティの記事

WAF(Web Application Firewall)とは？意味をわかりやすく簡単に解説
https://xexeq.jp/blogs/media/it-glossary2439

WannaCryとは？意味をわかりやすく簡単に解説
https://xexeq.jp/blogs/media/it-glossary2440

SQL Server 2022とAzure SQL MI間の双方向フェイルオーバーが一般提供開始、災害復旧とデータ移動性が向上
https://xexeq.jp/blogs/media/topics15320

vsftpdとは？意味をわかりやすく簡単に解説
https://xexeq.jp/blogs/media/it-glossary2433

カシオ計算機が社内ネットワークへの不正アクセスを公表、新製品発売延期とオンラインストア出荷遅延の影響
https://xexeq.jp/blogs/media/topics15219

JPAAWGが第7回年次カンファレンスを開催、ネットワークセキュリティの最新動向を議論
https://xexeq.jp/blogs/media/topics15311

ハッカーに次々に狙われる韓国の大学…個人情報から研究データまで標的に(10/13)
https://www.afpbb.com/articles/-/3543398?cx_part=top_category&cx_position=2

WaaS(Workspace as a Service)とは？意味をわかりやすく簡単に解説
https://xexeq.jp/blogs/media/it-glossary2438

サウジアラビアのフィンテック採用により、理想的なDeFiハブとなる、と専門家は指摘(10/13)
https://www.arabnews.jp/article/business/article_131516/
Zapier Interfacesで請求書業務を効率化してみた

こんにちは。
株式会社Oh my teethでテックリードをやっているTerukiです。

[前回の記事](https://qiita.com/omt_teruki/items/e94470c688088a7a3e50)からなんと一年以上も経過してしまいました。。

会社の急成長に伴い大変バタバタしていましたが、ちゃんと発信もしていきたいので今日から毎週定期的に技術記事を投稿していきたいと思います。

本格的な技術記事からゆるい記事まで書くつもりなのでお楽しみに！

今回の内容はゆるいタイプの記事でZapierを活用した請求書業務効率化の話です。

# TL;DR
- 毎月の請求書回収を効率化してみた
- Zapier Interfacesが便利
- 開発メンバー募集中

# 請求書業務を効率化したい
私は一応管理者の立場なので業務委託メンバーから請求書を受け取る立場なのですが、気づいたら二桁人のメンバーから毎月請求書を受け取るような規模になってました。

メールで請求書を受け取るのも中身を確認するのが大変なのでもうちょっとなんとかならないかと思っていたのですが、ちょうど良さそうなサービスがありました。
そう、Zapier Interfacesです。

https://zapier.com/interfaces

そもそもZapierは(ノ|ロ)ーコードのプラットフォームですが、その上でフォームを作れるようになった感じですね。

これがまあまあ便利でして、試しに雑にこんなフォームを作ってみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192685/9ea1b8ec-8fe1-3aa6-5742-2e672b65483a.png)

めっちゃシンプルですが、後続で処理を自動でできるように請求金額などをセルフで入れてもらう形になっています。（金額がPDFとあってるかは経理の人が確認するイメージ）

送信を押すと裏でガシガシZapierを動かすことができるので、電子帳簿保存法に適した形でファイルを保存したり、スプレッドシートに行を足したり、まあなんでもできます。

個人的に刺さったのは課金が必要にはなるのですが、カスタムドメインが使えたりテーマを自在に設定できたりするところですねｗ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192685/b9f8ea81-2878-c05a-8e8c-401564d8864a.png)


了承してくれたメンバーに先月実際に使ってみてもらったところ、いくつかフィードバックはありましたが概ね良さそうなので改善した上で全社展開できたらなと思っています。

もらったフィードバックはだいたいこんな感じでした。
- ちゃんと送信されたか確認できずちょっと不安
- 請求期限のカレンダーのUIがいけてない

ちゃんと送信されたかはメールアドレスを入力してもらうフォームを用意してZapierの最後の処理で完了した旨を通知するようにしようかなと。

カレンダーは英語圏仕様で確かに使いづらいのでここだけ不満ありです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192685/1e543f50-f9b0-49df-2f3b-d3405cf25abe.png)

それでも、概ねやりたいことはできているので今後のアップデートに期待ですね。

Zapierは3年以上使っているのですが、アップデートでどんどん良くなっているのでノーコードツールを探している人にはオススメです。
(Zapierの回し者ではありません笑)


だいぶゆるい感じですが今回はこの辺で。また来週の記事をお楽しみに。


# Oh my teethについて
Oh my teethでは未来の歯科体験を創るために日々活動しています。

Techチームではより良いユーザー体験を提供するべく、Webフロントエンドからバックエンド、スマホアプリに機械学習モデルなど、さまざまなプロダクトを開発しています。

一緒に未来の歯科体験を創りませんか？興味がある方は是非こちらを確認してください。

https://oh.careers/

カジュアル面談も可能なので気軽に応募してみてください！
Zodでその他の値の変化に応じてバリデーション条件を変える方法

## 結論: refineを使う
refineとは
> Zod を使用すると、改良を通じてカスタム検証ロジックを提供できます。(公式ドキュメントより)

これだけだとよくわからないが、refineはこの文の中にある、**カスタム検証ロジック**の実現に欠かせないメソッドということらしい。

## メソッドの仕様
```typescript
const freeText = z.string().refine(
    (val) => val.length <= 255, //val -> freeTextの値そのもの/戻り値はboolean
    {
      message: "String can't be more than 255 characters",//message -> falseの際に指定するバリデーションメッセージ
    }
);

```

## 今回の要件を満たすためには？
オブジェクトのバリデーションを定義してrefineメソッドを使用する。

```typescript
const freeObejct = z.object({
    value :z.number(),
    age: z.number()
}).refine(({ value, age }) => {
        if (age <= 18) {
            return false
        }
        return value >= 0;
    },
    { message: "1以上の値を入力してください。" },
)
```

## まとめ

かなり簡単に実装できた。
公式ドキュメントは少し理解しづらいのでZennなどのテックブログでこの類の情報は得た方がいい
VMwareのubuntuから他のubuntuに通信するとき（ROS2など）が上手くいかないとき

# 具体例
###### ・VMwareのubuntuからラズパイ4のubuntuとROS2で通信（talkerやlistenerなど）をやろうとした時に上手く行かなかった
###### ・SSHやpingは上手くいく

# 原因
###### ・VMware上のubuntuのネットワーク設定（NAT→ブリッジにするとうまくいく）
###### ・NATだと一旦ホスト（僕はWindows）を経由するけどブリッジはしないっぽい
###### ・ブリッジへの設定はアダプタ（WiFi含む）の設定に気をつける

# 教訓
###### ・仮想マシンから通信するとき、OSに依存するやつは気をつけなきゃいけない
【JavaScript】配列の応用まとめ①（条件抽出・マッピング）

こんにちは😺
だいぶ期間が空いてしまいました・・・
少しずつ落ち着いてきたので再開します:relaxed:

JS基礎学習、今回は`配列`の応用編①です！

## ▼配列の応用
### 1. 配列のフィルタリング（条件抽出）
配列の中から特定の条件に合う要素だけを抽出する。
` filter() ` メソッドを使って特定の条件を満たす要素を抽出する。

``` js
// 例: 偶数の要素を抽出
const numbers = [1, 2, 3, 4, 5, 6];
const evenNumbers = numbers.filter(num => num % 2 === 0);
console.log(evenNumbers); // [2, 4, 6]
 ```

＜応用例＞
- 商品リストの中の商品の在庫があるものだけを表示
- Todoリストの完了していないタスクだけを表示

### 2. 配列のマッピング（値の変換）

:::note info
**データマッピング（Data Mapping）**
異なるデータソースや異なるフォーマットのデータを変換・結合し、マッピング（対応付け）するプロセス
:::

`map()`メソッドを使う。
配列の各要素に対して同じ操作を行い、新しい配列を作成できる。
例えば、数値のリストを倍にしたり、オブジェクトのプロパティを変換することができます。

```js 
// 例: 各要素を2倍にする
const numbers = [1, 2, 3, 4];
const doubled = numbers.map(num => num * 2);
console.log(doubled); // [2, 4, 6, 8]
```

＜応用例＞
- 価格に税率を加える
- ユーザー名リストを表示名に変換

今回はここまで！
(Node.js) @mapbox/tilebeltモジュールを理解する

# はじめに
node.jsのコードの中で@mapbox/tilebeltモジュールを使用する機会があったので、どのようなモジュールであるのか簡単にまとめたいと思います。

# @mapbox/tilebeltモジュールとは
Mapboxが提供しているJavaScriptモジュールで、地図タイルを扱うための便利な関数が含まれています。

モジュールの主な機能には以下のものがあります。

1．タイル計算:
緯度経度からXYZタイル座標へ変換したり、逆にタイル座標から地理的な境界ボックスに変換したりできます。

2．親子関係の取得:
該当タイルの親タイルを取得したり、タイルを分割して子タイルを生成することができ、地図のズームインやズームアウトの操作に役立ちます。

# tileToBBOX()の使用方法
モジュールの中の一つのメソッドであるtileToBBOX()の使用方法の使用方法について解説します。これは、タイル座標から地理的なバウンディングボックス（BBOX）を取得する関数です。タイルは通常、ズームレベルz、x座標、y座標で指定され、地図の特定の領域を表します。tileToBBOX関数を使用すると、そのタイルがカバーする地理的な範囲（バウンディングボックス）を、緯度と経度の座標として得ることができます。

使い方の概要:
引数: [x, y, z] 形式のタイル座標
x: 横方向のタイル座標
y: 縦方向のタイル座標
z: ズームレベル

戻り値: tile がカバーする領域のバウンディングボックス [minLon, minLat, maxLon, maxLat] （最小・最大の経度と緯度）



# サンプルコード
```javascript:tilebelt.js
const tilebelt = require('@mapbox/tilebelt');

const tile = [10, 15, 8]; // x,y,z
const bbox = tilebelt.tileToBBOX(tile);
console.log(bbox);
```

## コードの解説


```javascript
const tilebelt = require('@mapbox/tilebelt');
```
@mapbox/tilebeltモジュールをインポートしています。

:::note info
@mapbox/tilebeltモジュールの最新バージョン2.0.0は、Node.js の標準モジュールシステムである CommonJSでサポートしていないexportキーワードが使用されているようです。そのため、バージョン1.0.2を使用します。CommonJS用に書き直すなどすると、最新版でも動くと思います。
:::

```javascript
const bbox = tilebelt.tileToBBOX(tile);
```
tileToBBOXメソッドを呼び出し、指定したタイル座標に基づいてバウンディングボックスを取得しています。この関数は、タイルがカバーする地理的な範囲を表す座標を返します。
バウンディングボックスは、最小の経度、最小の緯度、最大の経度、最大の緯度の4つの値から構成されます。

# 実行結果
```
[ -165.9375, 82.67628497834903, -164.53125, 82.8533822917608 ]
```
 [経度の最小値, 緯度の最小値, 経度の最大値, 緯度の最大値]の構成となっています。


# まとめ
node.jsの@mapbox/tilebeltモジュールの使用方法についてまとめました。

# Reference

https://github.com/mapbox/tilebelt
【Unity】SystemInfo.deviceUniqueIdentifierの罠（iOS）

## はじめに
AppStoreにてリリースしているアプリのとある処理で、`SystemInfo.deviceUniqueIdentifier`を使用していた。
`SystemInfo.deviceUniqueIdentifier`について、[Unity公式ドキュメント](https://docs.unity3d.com/ja/2022.3/ScriptReference/SystemInfo-deviceUniqueIdentifier.html)には以下のような記載がある。
> A unique device identifier. It's guaranteed to be unique for every device (Read Only).
> 
> iOS: Uses UIDevice.identifierForVendor to generate a unique device identifier.

ほう、固有のID！
同じデバイスなら必ず同じ値が返ってくるんや！と思ってたら、大目玉を喰らうらしい。
今回**TestFlight版とストアリリース版ビルドの行き来でも値が変わる**ことがわかったので覚え書き。

## 環境
OS: macOS Sequoia 15.0
Unity: 2022.3.12f1
iPhoneのOSバージョン: 18.0


## 経緯
私がAppStoreでリリースしているとあるアプリでは、動作確認などにTestFlightを使用している。
リリース後、不具合を見つけたので修正版を作りTestFlightへアップ。
動作確認のため、インストールされていた**ストアリリース版ビルド**（1.0.0）をそのまま更新する形で**TestFlight版ビルド**(1.0.1)にアップデートした。

すると予期せぬエラーが発生。
調べてみると、どうやら`deviceUniqueIdentifier`の値が変わったことによるエラーの模様。
ちなみに**TestFlight版ビルド**(1.0.0)→**TestFlight版ビルド**(1.0.1)では`deviceUniqueIdentifier`の値は変わらず、エラーは起きなかった。


## どういう時に値が変わるのか
`SystemInfo.deviceUniqueIdentifier`の値は、iOSにおいては`UIDevice.identifierForVendor`を使用して生成しているらしい。
[Apple公式ドキュメント](https://developer.apple.com/documentation/uikit/uidevice/1620059-identifierforvendor)には次の記載があった。
> The value in this property remains the same while the app (or another app from the same vendor) is installed on the iOS device. The value changes when the user deletes all of that vendor’s apps from the device and subsequently reinstalls one or more of them. The value can also change when installing test builds using Xcode or when installing an app on a device using ad-hoc distribution. Therefore, if your app stores the value of this property anywhere, you should gracefully handle situations where the identifier changes.

DeepL先生↓
> このプロパティの値は、アプリ（または同じベンダーの別のアプリ）がiOSデバイスにインストールされている間は同じままです。 ユーザーがデバイスからそのベンダーのアプリをすべて削除し、その後 1 つまたは複数のアプリを再インストールすると、値は変更されます。 また、Xcode を使用してテストビルドをインストールするときや、アドホック配布を使用してデバイスにアプリをインストールするときにも値が変わることがあります。 したがって、アプリがこのプロパティの値をどこかに保存する場合は、識別子が変更される状況を優雅に処理する必要があります。

つまり、
① 同一デベロッパが作ったアプリを端末から一掃して、再インストールした場合
② Xcodeを使用したテストビルドをインストールする時
③ AdHoc配布のビルドをインストールする時

に変わる可能性があって、TestFlightは②に当てはまるってコト…？
端末には同一デベロッパの他のアプリもインストールされていたので①には該当せず、その可能性が高い。

③に関しては、使用する配布方法によっても変わるっぽい。
Firebaseの「AppDistribution」では、アップデートでビルドを更新するたびにエラーが起きていたので、値が変わってたと思われる。
一方、「DeployGate」でのアップデートや、Xcodeの「Device and Simulator」から直接ipaを書き込んだ場合はエラーは起きなかったので、この場合は変わらないと見られる。

## おわりに
`SystemInfo.deviceUniqueIdentifier`を使う場合は、値が変わることを前提とした優雅な設計にしましょう！