OmniAICreator/Qiita-1.07M huggingface dataset:
Vite + Jest｜環境変数 import.meta.env を使う設定方法

Vite 環境でテストするためにJestを実行すると、`process.env` が `undefined` になる場合があります
これは、Vite では `import.meta.env` を使用する仕様になっているため、Jest で `import.meta.env` を直接利用できないことが原因です。
Vite でも Jest でも `process.env` を統一して使用する方法を紹介します。


## 前提条件
- Vite + React 環境 で開発を行っている
- Jest + React Testing Library を使用してテストを実行
- 環境変数 (`import.meta.env`) を `.env` に定義している
- Supabase などの API キーを `.env` で管理している
- テスト時にも環境変数を適用し、正しく動作するか検証したい



## `process.env` が使えない原因

- Vite は `import.meta.env` を推奨しており、デフォルトでは `process.env` をサポートしていません
- Jest は `import.meta.env` をサポートしていないため、`undefined` になってしまいます
- 環境変数を統一するには、Vite の設定を変更する必要があります

## Vite の設定

`vite.config.js` に `define` を追加し、`process.env` を Vite でも利用できるようにします。

### `vite.config.js`

```javascript
import { defineConfig } from "vite";
import dotenv from "dotenv";

// `.env` を読み込む
dotenv.config();

export default defineConfig({
  define: {
    "process.env": process.env, // Vite でも `process.env` を使えるようにする
  },
});
```

### `.env`

```env
VITE_SUPABASE_URL=https://your-supabase-url
VITE_SUPABASE_ANON_KEY=your-anon-key
```

**ポイント**

- `dotenv.config();` で `.env` を `process.env` に適用
- `define: { "process.env": process.env }` で Vite 内でも `process.env` を使えるようにする
- `.env` の変数は `VITE_` をつける必要がある

## Supabase クライアントの設定

`supabaseClient.js` では `process.env` を使用するように修正します。

### `supabaseClient.js`

```javascript
import { createClient } from '@supabase/supabase-js';

export const supabase = createClient(
    process.env.VITE_SUPABASE_URL,
    process.env.VITE_SUPABASE_ANON_KEY
);
```

## Jest で `.env.test` を読み込む

Jest のテスト環境用に `.env.test` を作成します。

### `.env.test`

```env
VITE_SUPABASE_URL=https://your-test-supabase-url
VITE_SUPABASE_ANON_KEY=your-test-anon-key
```

### `jest.setup.js`

```javascript
import dotenv from "dotenv";
dotenv.config({ path: ".env.test" });
```

## 動作確認

- Vite 開発環境で `console.log(process.env.VITE_SUPABASE_URL);` を実行し、値が取得できることを確認
- Jest 実行時も `console.log(process.env.VITE_SUPABASE_URL);` を出力し、正しく読み込まれているか確認

## まとめ

- Vite では `import.meta.env` を使うが、Jest では `process.env` を使用する
- Vite の `define` を設定することで、`process.env` を統一できる
- `.env` と `.env.test` を分けることで、開発環境とテスト環境を分離できる

これで Vite でも Jest でも `process.env` を統一して使用できます。

https://ja.vite.dev/config/shared-options.html#define
rex0220 印刷屋プラグイン 書式画像を背景に

rex0220 印刷屋プラグイン 書式画像を背景にして領収書を作ってみます。
出来ないことはないが、位置合わせが面倒なので作るのが大変です。

# 概要

下記のような手順で、書式を取り込んで項目を配置すれば、できそうです。
結構面倒な作業なので、宛名だけ試してみました。

- Excel で作った領収書の書式を png 画像にして、kintone の添付ファイルに入れる
- 印刷屋プラグインのページに、背景画像として設定
- 各項目を領収書の書式に合わせて配置（ブラウザーの開発ツール）を調整


![2025-02-28_08h54_23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/d3ba3697-3833-4b3c-a6cb-4f0aaa0c1b28.png)

# ブラウザーの開発ツールで位置調整

領収書の書式位置を基準として、項目の top, left 等を指定して表示位置を合わせます。

![2025-02-28_09h03_30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/aad325ef-5816-4edb-8cbe-273e71e8bc05.png)


# 印刷屋プラグイン設定

書式画像を背景にした div を設定し、その要素として、各項目を追加します。

![2025-02-28_09h06_38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/ca804d67-5beb-4d8f-a1f1-3593626ed3b8.png)

![2025-02-28_09h07_12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/1c429319-4652-4224-97a8-633fa5c2ea69.png)

```css:
.pcraft-back-image {
    position: relative;
    width: 100%;
    height: 100%;
    background-size: contain;
    background-repeat: no-repeat;
}
```

```html:
<div class="rex0220-pcraft-page">
    <div class="pcraft-back-image" style="background-image: url(#{&f(20250227231325D28DBAB4BF7A453EB4A2BA388F8195E9054)})">
        <div style="position: absolute; left: 30px; top: 110px; font-size: 22px;">
            ${宛名}
        </div>
    </div>
</div>
```
【Teams電話】個人用電話番号 (プライベートライン)

# はじめに

Teams 電話ではユーザーに 2 つ目の電話番号を個人用電話番号 (プライベートライン) として割り当てることができます。この電話番号と通常の電話番号 (プライマリ電話番号) との違いについてまとめました。

# 個人用電話番号とは？

個人用電話番号は、通常は代理人などへ着信を転送しているユーザーに対して、直接ユーザーを呼び出すことができる 2 つ目の電話番号です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680397/caa971d3-a23b-4872-8d81-2f9ac8109d14.png)


個人用電話番号はプライマリ電話番号と異なり、ユーザーの代理人や同時呼び出しなどの転送設定に関わらず、直接ユーザーに着信します。限られた人だけに教える直通電話番号のイメージです。

::: note warn
ユーザーが個人用電話番号を使用して外線発信することはできません。
:::

(参考：Microsoft Teamsでプライベート回線を構成する)
https://learn.microsoft.com/ja-jp/microsoftteams/private-line

# 個人用電話番号の割り当て

個人用電話番号は Teams 管理センターのユーザー管理画面から割り当てることができます。[個人用電話番号の割り当て] ボタンからプライマリ電話番号と同様に割り当てます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680397/b80f9ee5-010e-4ef1-a8f5-3a6f061bab72.png)

::: note
Teams PowerShell で割り当てる場合は -AssignmentCategory Private を指定します。
:::
```powershell
Set-CsPhoneNumberAssignment -Identity "user01@atsmin.net" -PhoneNumber '+815012345678' -PhoneNumberType DirectRouting -AssignmentCategory Private
```

# 着信時の動作

個人用電話番号への着信は、通知のポップアップから区別することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680397/5c56af16-3b50-48cc-bf38-980da80dc179.png)

また、着信履歴にも [プライベート番号] と表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680397/0aac381a-292f-447d-b373-0244b99ef0b4.png)
Cloud Scheduler から Workflows を呼び出す Terraform コード

Terraform で Cloud Scheduler から workflows を呼び出すコードを書いてたらハマったので備忘録のついでに記事にしました。

### 完成形のコード

```terraform
resource "google_cloud_scheduler_job" "sample" {
  name        = "sample"
  description = "サンプル"
  schedule  = "0 * * * *"
  time_zone = "Asia/Tokyo"
  project   = var.project_id
  region    = var.region
  http_target {
    uri = "https://workflowexecutions.googleapis.com/v1/projects/${var.project_id}/locations/${var.region}/workflows/${google_workflows_workflow.sample.name}/executions"
    oauth_token {
      scope                 = "https://www.googleapis.com/auth/cloud-platform"
      service_account_email = google_service_account.trigger_scraping_schedule.email
    }
    http_method = "POST"
  }
}

# IAM
resource "google_service_account" "scheduler" {
  account_id  = "scheduler"
  description = "スケジューラ用サービスアカウント"
}
resource "google_project_iam_member" "scheduler" {
  for_each = toset([
    "roles/workflows.invoker"
  ])
  role    = each.value
  member  = "serviceAccount:${google_service_account.scheduler.email}"
  project = var.project_id
}

resource "google_workflows_workflow" "sample" {
  name            = "sample"
  region          = var.region
  description     = "sample"
  service_account = google_service_account.sample_workflows.email
  call_log_level  = "LOG_ERRORS_ONLY"
  source_contents = file("your_workflow_path.yaml")
  user_env_vars = {
    PROJECT_ID = var.project_id
    REGION     = var.region
  }
}
```

### ハマったポイント

本来 oauth_token でアクセスすべきところを oidc_token でアクセスしようとしてたためエラーが出ました。
Cloud Run Functions に対して http トリガーで実行してるのをコピペしたためうっかりしてしまいまし
Databricks の課金を理解する：課金の仕組みと注意点について解説

みなさん、こんにちは！

AWS、Azure、Google Cloud を基盤として構築可能なデータ分析プラットフォームである Databricks。
クラウドの利点を活かした統合的なデータ分析基盤を簡単に構築できて便利ですが、課金についてわかりにくい部分があったため調査しました。
Databricks の課金の仕組みと注意点について、具体例も交えながら解説していきます。

## 課金の仕組み
Databricks の課金対象となる要素は大きく以下の4つです。

 * Computeリソース
 * ストレージ
 * DBU（Databricks Unit）
 * サービスプラン
それぞれについて詳しく見ていきます。

### Computeリソース
Databricks では、クラウドプロバイダ（AWS、Azure、Google Cloud）の仮想マシン（VM）を使用してクラスターを構築します。 
そのため、クラスターに使用する VM の種類や数、使用時間に応じて料金が発生します。

### ストレージ
Databricks では Delta Lake と呼ばれる空間にデータを格納しますが、それはクラウドプロバイダのオブジェクトストレージを基盤としています。 
AWS の場合は S3、Azure の場合は Azure Blob Storage、Google Cloud の場合は GCS が使用され、ストレージ料金が発生します。

### DBU（Databricks Unit）
Databricks には DBU（Databricks Unit）と呼ばれる消費リソースの測定単位があります。
Compute リソースとデータ処理量に応じて異なるDBU料金が適用される形となっており、特にクラスター作成の際のオプション（シングルノード/マルチノード、Photon の使用有無など）によって大きく変わります。
DBU料金は時間単位で計算され、計算式は以下のようになります：
**DBU料金 = VM稼働時間 x VM性能 x オプション**

### サービスプラン
Databricks には Standard、Premium、Enterprise といった料金プランがあり、それぞれのプランに応じて異なる機能と料金が設定されています。
上位プランは機能が充実し、セキュリティや管理機能も強化されていますが、そのぶんDBUあたりの料金も高くなります。

## コスト例
Azure Databricks で、Standard プランで最小のクラスター構成で利用する場合について試算しました。
今回想定した条件は以下の通りです。

 * クラスター構成
・インスタンスタイプ：Standard_F4（4vCPU, 8GB RAM）
・クラスターサイズ：1ノード
・DBU：0.50
 * ストレージ
・データストレージ：Azure Blob Storage
・データ量：100GB
 * DBU料金
・料金プラン：Standard
・DBU料金：$0.400
 * 使用期間
・1日4時間 x 20日 = 80時間
この場合、コストは以下のようになります。

 * Computeリソース
・インスタンス料金：$0.252/時間
・稼働時間：80時間
・リソース費用：$0.252 x 80 = $20.16
 * ストレージ
・データ量：100GB
・ストレージ費用：100 x $0.0184 = $1.84
 * DBU料金
・DBU使用量：1ノード x 80時間 = 80DBU
・DBU費用：80 x $0.400 x 0.50 = $16
**合計：$20.16 + $1.84 + $16 = $38**

上記の例からもわかるように、大量にデータがない限りストレージ料金はほとんどかかりませんが、Compute リソースとDBU料金は大きな割合を占めます。
どちらも時間に比例して高くなるので、クラスターの自動停止設定をするなど長時間の稼働を避けることが重要です。

## 注意点
上記の内容も含め、Databricks の課金の注意点をまとめると以下の通りとなります。

### 基盤リソースの費用と Databricks の費用は別
Databricks はクラウドサービス上にデプロイされ、基盤リソースも基本的には Databricks 側で管理されますが、Databricks 自体の費用と基盤リソースの費用はしっかり別になっているため注意が必要です。
Computeリソース、ストレージ、DBU料金の合計が全体の費用となります。

### デフォルト設定のまま使わない
Databricks はデフォルトの設定だと高スペックのクラスターが設定されていたり、オートスケーリングや Photon（高性能クエリエンジン）の使用が有効になっていたりとある程度パワフルな構成になっています。デフォルトのままでいいや、とリソースを作成すると高くつく可能性が高いので、適切な構成に変更して使うことを強く推奨します。

クラスターやパイプラインなど、リソース作成画面に「サマリー」としてDBUの値が表示されているので、現在のDBUを確認しながら設定するようにしましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3956386/c5bd762b-a7f5-4430-bd7b-799e89b96589.png)

### 計算リソースを長時間稼働したままにしない
コスト例でも言及しましたが、計算リソースの使用時間に比例して課金額が大きくなってしまうため、自動停止設定などを利用して長時間稼働しないようにすることが大切です。

クラスターの場合、「非アクティブ状態が〇分継続したら終了」という設定が簡単にできるので、忘れず設定しておきましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3956386/461f5d39-a25a-4960-a56d-37be7f278967.png)

## 最後に
Databricks は簡単に導入できて便利ですが、課金システムがわかりにくく、何も考えずに使っているとコストが肥大化しやすいという落とし穴があります。

本記事の内容を参考に、Databricks を賢く利用して運用コスト最適化に繋げていただければ幸いです。

### 参考記事
 * [Databricks ご利用料金 | Databricks](https://www.databricks.com/jp/product/pricing)
 * [Azure Databricksのコストが肥大化する罠](https://cloudsteady.jp/blog/2024/08/10/79029/)
保険について5

## 初めに
皆さんこんにちは、大野です。
今回は前回紹介した保険の説明の続きです。

※前回も説明しましたが、保険商品の内容は保険会社によって細部が違います。当記事だけで納得しないでご自分でも調べてください。

## 転車保険
自転車保険は、自転車事故による運転者のケガや、相手への損害賠償に備えるための保険です。インターネット経由やサイクルショップ、自転車安全整備店、コンビニエンスストア、保険代理店等、さまざまな場所で加入が可能です。

近年、自転車による重大事故で高額な賠償責任が生じるケースもあるため、多くの自治体では、自転車保険への加入義務化または努力義務化が進んでいます。自転車保険への加入が義務化・努力義務化されている地域に住んでいる人をはじめ、日常的に自転車を使用する人も、自転車保険に加入しておくと安心でしょう。

## 傷害保険
傷害保険は、日常生活におけるケガに備える保険です。ケガによる死亡や、入院・通院の際に、保険金が受取れます。スポーツ中や通勤中、旅行中、交通事故によるケガ等、補償対象は幅広いものの、「急激な事故」「偶然な事故」「外来的な事故」の3つに該当することが条件となります。なお、病気は補償対象外です。

## 所得補償保険
所得補償保険は、病気やケガによって働けなくなった場合の、所得の損失分を補償する保険です。保険金額は、公的医療保険からの給付内容等を考慮した上で、保険契約締結直前12か月における平均月間所得の50～70％で設定することが一般的です。平均月間所得額を上回る保険金を受取ることはできません。

## 海外旅行傷害保険
海外旅行傷害保険は、海外旅行中のトラブルや損害に備えるための保険です。例えば、海外旅行や海外出張、留学等で渡航した際の、病気やケガによる死亡・後遺障害・治療費用や、賠償責任、携行品損害、救援者費用等が補償されます。

なお、クレジットカードの中には、海外旅行傷害保険が付帯されているものがあります。海外旅行傷害保険への加入を検討する際には、クレジットカードの付帯保険の補償内容や条件等を、事前に確認しておくとよいでしょう。

## ペット保険
ペット保険は、ペットの病気やケガに備えるための保険です。主な補償内容は、ペットの入院・手術・通院です。また、保険商品によっては、ペットが他人にケガをさせたり、他人の物を壊したりして損害賠償責任を負った際に補償が受けられる特約を設けているものもあります。

## ゴルファー保険
ゴルファー保険は、ゴルフのプレー中のケガや他人への賠償費用、ゴルフ用品の破損・盗難等、ゴルフに関わるリスクにまとめて備える保険です。ゴルフ中のトラブルだけではなく、ホールインワンやアルバトロスを達成した際の、祝賀会や記念品の購入費用等も補償対象となります。

## 最後に
今回の記事まで計5回の記事で保険について説明してきました。
保険は適切に使えばとても心強いお守りになりますが、自分にとって意味のないものや不適正な金額を掛けてしまうと意味のないものどころか自分に不利益をもたらします。ぜひ当記事だけでなくいろいろな情報を調べて自分に適切な保険を探してみてください。
お読みいただきありがとうございました。
以上大野でした。
Prologチェッカー

# 発端
この度、N-Prologのコンパイラを大幅に改良しました。TCOを入れた関係です。コンパイラはPrologでおよそ２０００行ほどになりました。そうしますと小さなコードであれば容易に発見できたミスも発見が難しくなることがわかりました。そこでver4.0においてCheckerライブラリを追加しました。

# 誤airty検出
次の例ではfact/2の呼び出しで引数を間違えています。

```
fact(0,1).
fact(N,X) :-
        N1 is N-1,
        fact(N1,X1,2),
        X is N*X1.
```
このようにして検出されます。

```
?- check_file('./tests/fact.pl').
detect arity fact(varN1,varX1,2) in fact(varN,varX)
yes
?- 

```


# singleton検出
次の例では変数のタイプミスをしています。

```
fact(0,1).
fact(N,X) :-
        N1 is N-1,
        fact(N1,X2),
        X is N*X1.


```

次のように検出されます。

```
?- check_file('./tests/fact.pl').
detect singleton varX2 in fact(varN,varX)
detect singleton varX1 in fact(varN,varX)
yes
?- 

```


# タイプミス検出
次の例では頭部の述語名のタイプミスをしています。

```
fact(0,1).
facT(N,X) :-
        N1 is N-1,
        fact(N1,X1),
        X is N*X1.

```

次のようにして検出されます。

```
?- check_file('./tests/fact.pl',full).
detect single clause facT(varN,varX):-varN1 is varN-1,(fact(varN1,varX1),varX is varN*varX1)
yes
?- 

```

このようなタイプのミスは１つだけ節がある場合という条件で検出しています。そうしますと正常なコードでも誤検出してしまいます。そこでこれはfullオプションをつけた場合にだけ検出する仕様としています。大きなコードになってくるとつまらないタイプミスで悩んで時間を浪費してしまうことがあります。Checkerで凡ミスを検出してしまいます。


N-PrologはOSSとして公表しています。ぜひ、お試しください。
https://github.com/sasagawa888/nprolog
Prologにおける末尾再帰最適化(2)

# 原因判明
N-Prolog　ver3.98で末尾再帰最適化（TCO)を導入しました。これにはまだバグがあり次のコードで動作していませんでした。

```prolog
fact(N, X) :- fact_(N, 1, X).
fact_(N, P, X) :- N > 0,
    N1 is N - 1,
    P1 is P * N,
    fact_(N1, P1, X).
fact_(0, X, X) :- !.

```

fact_/3はXに計算結果が累積されます。TCOによりループに変換されます。再帰動作ですとXはX->X'->X''と変数が連鎖していくのですが、繰り返しのため破壊的に変数に代入しています。変数の連鎖はありません。そうすると基底においてXの値が求まったとしても呼ぼだしもとの変数Xとのリンクが途切れてしまっています。そこで基底においては改めて呼び出しもとの変数とのUnifyが必要でした。コンパイラを改良してver4.00でTCOが完全動作するようになりました。

# red-cut と　green-cut
上記のコードは本来は下記のように書きます。green-cutというのだそうです。上記のように基底にカットを使うのはred-cutというのだそうです。

```prolog
fact(N, X) :- fact_(N, 1, X).
fact_(N, P, X) :- N > 0,
    N1 is N - 1,
    P1 is P * N,
    fact_(N1, P1, X).
fact_(0, X, X).

```

基底においてカットを使っていません。本体部でN > 0をもたせているのでバックトラックすることがありません。
しかし、これをコンパイラに理解させるのは手間がかかります。静的解析により計算しようとしている内容を把握しないといけません。意味論までかかわることになります。そこでN-Prologでは簡易的に本体部が！で終わっているかどうかで決定性を判別するようにしています。これによりコンパイラは簡単ですみます。




# 非効率
さて、TCOが機能したのでqsort/3を最適化してみるとかえって遅くなるのです。

```prolog
% Quicksort
qsort([X|L], R, R0) :-
    partition(L, X, L1, L2),
    qsort(L2, R1, R0),
    qsort(L1, R, [X|R1]).
qsort([], R, R) :- !.

% Partition list for quicksort
partition([X|L], Y, [X|L1], L2) :-
    X < Y, !, partition(L, Y, L1, L2).
partition([X|L], Y, L1, [X|L2]) :-
    !,partition(L, Y, L1, L2).
partition([], _ , [], []) :- !.

```

第１節の本体部においてqsort/3が２回出現します。最初の方は再帰呼び出しをし、２回めの方はループになります。これだと遅いのです。理由は変数の連鎖にあります。変数Rにソート結果が蓄積されます。最初のqsortは再帰呼び出しをされており変数の連鎖になっています。ところがそのあとのqsortは繰り返しにするために破壊的代入しその際にderefをしています。変数の連鎖をderefすると時間がかかるのです。

そういうわけでこのqsortのような２回呼び出される場合にはTCOにせず普通に決定性述語として再帰呼出しをすることにして速度を改善しています。


N-Prologは下記においてOSSとして公開しています。ぜひ、お試しください。
https://github.com/sasagawa888/nprolog
【SwiftUI】元Viewを再表示する際に、Viewを再描画し値を更新する方法

# はじめに
※この投稿はメモ程度の投稿です。
この記事は、SwiftUIでNavigationLinkを利用し、Viewを移動する際に、遷移先のViewでの値の変更を元のViewに反映させるための方法を示します。やり方としてはViewを再描画させる方法です。

# ソースコード
```Swift
@State private var refreshID = UUID()

var body: some View {
    List {
        ForEach(items) { item in
            Text(item.name ?? "No Name")
        }
    }
    .id(refreshID) 
    .onAppear {
        refreshID = UUID()
    }
}
```

# 説明
簡単に説明をします

```Swift
@State private var refreshID = UUID()
```
上記の部分で、初期のUUIDを指定



```Swift
 .id(refreshID) 
```
IDが変わったら新しく再描画する処理

```Swift
.onAppear {
    refreshID = UUID()
}
```
再度新しいUUIDを格納する
Laravel Gmail送信

１アプリパスワードを作成
https://myaccount.google.com/apppasswords

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80232/ecb142bc-70cd-4db1-8d1f-336d2df91380.png)

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80232/c808e37f-b839-444b-b567-98b453564313.png)

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80232/da08bdfb-749b-460d-823f-c76d90dc5835.png)

![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80232/401c763e-8cc7-409e-803d-c89c11dcedfa.png)

２.envファイルを設定
MAIL_MAILER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME=hoge@gmail.com
MAIL_PASSWORD=16文字のパスワード
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS="${MAIL_USERNAME}"
STM32F042、フィボナッチ数列で遊ぶ(UNO3比8倍程度)(ベンチマークテスト)(理系フリマで買った)



目的

整数のベンチマークする



いろいろ

シンセ先輩からほぼ貰う。(mbed終わっちゃし
f042は、内臓USB付き、たが、まともに動かない
理系フリマ　(20250301)(土)


Arduino UNO R3は、約17542msで
は、約2170msで約8倍、速い
理由は、不明

Arduino UNO 3 約17542ms(18秒)
M5NanoC6 約336ms(0.3秒)
M5StampS3 約328ms(0.3秒)
STM32H743 約72ms(0.072秒)


結果

![Screenshot from 2025-02-28 07-57-26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/5afc8ac6-b77e-4c1a-b08c-4bde38f65e1c.png)


プログラム


```c++


//値が100,000を超えるまでのフィボナッチ数列を生成する作業を500,000回繰り返すのに要した時間を計測する。
#define DEBUG 0
void setup() {
  Serial.begin(9600);
  Serial.println();
  Serial.print("START");
  for(int i = 0;i < 9;i++){
    Serial.print('.');
    delay(500);
  }
  Serial.println();
}
void loop() {
  unsigned long x;
  unsigned long prevx;
  unsigned long temp;
  unsigned long start_time, end_time;
  unsigned long time;
  start_time = millis();
  for (unsigned long a = 0; a < 500000; a++) {
    x = 1;
    prevx = 0;
    while (x < 100000) {
      temp = x;
      x = prevx + x;
      prevx = temp;
#if DEBUG
      Serial.println(x);
#endif
    }
  }
  end_time = millis();
  time = end_time - start_time;
  Serial.print("END Value:");
  Serial.println(x); //最後の値の出力
  Serial.print("StartTime:");
  Serial.print(start_time);
  Serial.print(" EndTime:");
  Serial.print(end_time);
  Serial.print(" Time:");
  Serial.println(time);
  delay(1000);  //1秒待機
}


```
Teachable Machineで作った『商品カラー判定ツール』でECサイトへのカラーバリエーション設定を楽ちんにした話

こんにちはhiro-isakaこと『ひろ』です🐶
いろいろありましてペンネーム改名しましたm(__)m

私は小売業のECショップの担当をしていますが担当業務は幅が大変広～くて商品発掘から商談、ショップシステムへの登録、受発注、お客様対応などなど∞

今回は、ECサイトの商品登録業務に大きく貢献してくれる『カラーバリエーション』の設定に役立つツールを[Teachable Machine](https://teachablemachine.withgoogle.com/ "Qiita Home")を使って作ってみました。

🌈私が他の業務改善について書いた記事です

https://qiita.com/hiro-isa/items/e8cc1e0e87fe501a712c

# カラーバリエーション設定とはなによ？
![karabari.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3962617/386f2541-52ef-4880-83e2-d3cc440cc04d.jpeg)


商品仕様の一部で、<font color="red">商品の代表カラーの設定</font>のこと。
もちろん商品の画像もあるからそれで確認すれば済む話ですが、検索キーワードで引っかかりやすくなる嬉しいメリットがあるし、そもそも設定しないと商品登録が完了できないので必須項目になります。

バナナ🍌のような単色の商品なら当然「イエロー」って登録するけど、いろんなカラーが混在する商品だと困りますよね。
シマウマ🦓のぬいぐるみだったら「ブラック」「ホワイト」どっちなの？って。

# Teachable Machineを使ってみよう🎉

:::note info
**Class登録やサンプル画像アップロード画面までの道のりはこちらを参考に!**
:::
https://x.com/isahio_ken/status/1895078516963889535
#### まずはいろいろな準備をするよ
:::note warn
①Classの作成（今回は、赤系、緑系、茶系、黄色系、ベージュ系の５つ）

②サンプル画像をそれぞれのカラーのClassへアップロード

③アップロードした画像を覚えさせるためモデルをトレーニング
:::
![tm_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3962617/ddf63ab5-26f7-486e-a1a5-9f6b8b90c8d1.jpeg)

#### 次に
:::note warn
④モデルをエクスポート
:::
![tm_2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3962617/367c81e5-1314-4977-b338-976395aaaa70.jpeg)


#### ここからがプログラマーっぽい💻
:::note warn
⑤`Tensorflow.js`を選択
:::
![tm_3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3962617/475ca7a8-f67e-4428-b374-cea7a4ac0c9c.jpeg)

:::note warn
⑥`Javascript`を『メモ帳』に貼り付けて`html`で保存
:::
![tm_4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3962617/c7e63fc0-28a7-4117-894d-d7d036e2cb00.jpeg)

※ローカルで使用したかったので『メモ帳』さんにご協力いただきました。

# ここからが試行錯誤の繰り返し😑

最初はカメラに映った商品画像のカラー判定する仕様だったけど、アップロード画像のカラー判定をする仕様にしたかったのでコードの変更を毎日何度も[ChatGPT](https://openai.com/ja-JP/chatgpt/overview/ "Qiita Home")さんに聞きました。

その都度快く教えてはくれるのだけど、あまり聞きすぎると『今日はもう終わりよ！これ以上は答えられないわ🙅』と言われ、機嫌が直るまで数時間待つ始末🤣

やっとできあがったコードはやっぱり呪文にしか見えないけど絵文字を入れたり、表示される文字の大きさや色も変えたりと苦手な`html`とも向き合ってやったぜ✊

# そして出来上がったのがこれ！

https://x.com/isahio_ken/status/1895081521498988721

黄色いバナナなのになぜか<font color="#8b4513">**ベージュ系**</font>と出るの💦なんでかな―？

# 本当にやりたかった事
本当は<font color="red">アップロードした商品画像</font>と<font color="red">カメラで映した商品</font>のカラー判定の二刀流ツールを作りたかったのですが、ここは何度[ChatGPT](https://openai.com/ja-JP/chatgpt/overview/ "Qiita Home")さんに聞いても上手くいきませんでした😢

![botu.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3962617/5225bc34-7ec7-42a2-980e-58321e5c8e0b.jpeg)


両方のボタンは作れるけど片方しか動かない状況になってしまうのでめっちゃ残念だけど
ここは一旦諦めて、アップロードした商品画像の判定ツールとして作りました。

今回は理想の形にはならなかったけど諦めずに、二刀流ツールを完成させたいと思います✊🏻

最後まで読んで頂き、ありがとうございました💖
Check New Lead for Matching Account flowのエラー


# In the 'Check New Lead for Matching Account' flow, we can’t find the flow optimized for 'Actions and Related Records'.

+ [In the 'Check New Lead for Matching Account' flow, we can’t find the flow optimized for 'Actions and Related Records'.](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007W5L4N)

:::note
Make sure you have this option selected in your flow

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/3bfff506-5ef8-6a25-45a2-810f7e058f6c.png)
:::

+ [I don't find the flow "Check New Lead for Matching Account"](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX000000NN8y)

# In the 'Check New Lead for Matching Account' flow, we can’t find the flow optimized for 'Fast Field Updates'.

+ [I am trying to complete Combine Variables and Data Module. I keep receiving the following error message:](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V000076AEDU)
+ [I don't find the flow "Check New Lead for Matching Account"](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX000000NN8y)

:::note
Make sure you have this option selected in your flow

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/3bfff506-5ef8-6a25-45a2-810f7e058f6c.png)
:::

#  In the 'Check New Lead for Matching Account' flow, I am encountering an issue where the text template with the API name 'ChatterMessage' is missing.

+ ["Missing 'ChatterMessage' Text Template in 'Check New Lead for Matching Account' Flow"](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX000000UXSv)

:::note
If you have an old version of the flow, try deleting it 


https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007O3WA1
:::
サッカー(JOI 16回 本選) の解説の行間埋め

# はじめに
おはようございます。本記事では、私が[JOI サッカー](https://atcoder.jp/contests/joi2017ho/tasks/joi2017ho_d) の解説を読んでいて詰まった部分の行間を埋めることを目指します。


# 何に詰まったか
解説スライド41Pにある
> ▶ シュートされたあと誰かに拾われるわけですが、この時、同じ選手が二回ボールを蹴らないという考察から、(初期位置が) 一番近くの人が拾えば良いことが分かります。

という記述の正当性を疑問に思いました。より具体的には、
1. それが最適値をだすのか
2. 対応する操作列が存在するのか

の $2$ 点が気になりました。よって、これを納得する事を目標にします。

# 記法
「$(i, j)$ にボールがあり、かつ誰もボールを持っていない」状態を $(0, i, j)$ と置きます。  

「$(i, j)$ にボールがあり、かつボールを持っている人が居る」状態を $(1, i, j)$ と置きます。

また、状態 $(t, i, j)$ になる操作列のうち、コストが最小のもののそのコストを $d(t, i, j)$ と置きます。


# 前提
次の命題を認めます。
命題:操作列を任意に取る。この時、次の条件を満たす操作列であって、取った操作列以下のコストである物が存在する。

> $\forall i,$ 人 $i$ がボールを $1$ 回以上持ち、かつ手放したならば人 $i$ は以降ボールを持たない

<br>

よって、同じ人は $1$ 回までしかボールを持たないと制約をかけても最適解が求まります。なので今後はそうします。

また、次も認めます。
>ということは、選手 1 の初期位置からはじめて -> ドリブル
をする -> シュートをする -> ある選手がボールの位置に移動
する -> ドリブルをする -> シュートをする -> ある選手が
ボールの位置に移動する -> ... -> ドリブルをする -> (シュー
トをする) -> ボールが選手 N の初期位置に到達する という
流れのみを考えればよい。

つまり、人はボールを持つ直前まで一歳動かないと制約をつけます。

# 命題
早速、
> ▶ シュートされたあと誰かに拾われるわけですが、この時、同じ選手が二回ボールを蹴らないという考察から、(初期位置が) 一番近くの人が拾えば良いことが分かります。

を証明したいのですが、そもそも"良い"という主張は命題ではなく、今回証明の対象とするにはやや曖昧で取り扱いに苦労します。よって、次の命題を示すことにします。

命題: 任意の $i, j$ について、 $(i, j)$ に初期位置が一番近い人を $k$, 人 $k$ から $(i, j)$ までのマンハッタン距離を $d$ と置くと、次が成立する。
$$ d(1, i, j) \le d(0, i, j) + d$$

# 証明




$d(0, i, j)$ を実現する操作列を任意に $1$ つとる。

## 1. 人 $k$ が $(0, i, j)$ に至るまでにボールを持たなかった場合

取った操作列に人 $k$ の動きを加えた操作列のコストが $d + d(0, i, j)$ である。

## 2. 人 $k$ が $(0, i, j)$ に至るまでにボールを持っていた場合
注意: $(0, i, j)$ の時点で人 $k$ がどこにいるかは不定である。

構成的な証明をする。
黒で人 $k$ を表す。
![メモ 2025-02-26.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3995933/ce48d91f-7eee-4405-8ada-5b4e371e8baf.jpeg)


を元の操作列とする時、

![メモ 2026.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3995933/ff36f9bd-999b-452a-a35a-7dce6c214a19.jpeg)

の様に改変した操作列のコストは $d(0, i, j) + d$ 以下で、状態が $(1, i, j)$ である。

より正確には、
1. 人 $k$ のボールを持つまでの移動を直前の人のドリブルで置き換える(コスト不変。ボールの位置は変化する)。
2. 人 $k$ から起こる一連の操作を全て捨てる(コスト減)
3. 人 $k$ から $(i, j)$ に行く(コスト $+d$ )

よって、命題は示された。

# 最短経路との対応
命題の不等式が成立するからと言って最短経路と答えが対応することは自明ではないと思います。$d(1, i, j) = - \infty$ でも一見すると良いわけで、 $d(0, ?, ?)$ と $d(1, ?, ?)$ の関係がまだ不明瞭です。でも、ここまでで疲れたので考えません。ごめんなさい。言うもおろかってやつです。

真面目に考えると、命題の系として次が直ちに得られます。

系(パス -> 操作列の対応): 解説の通りに辺を貼ったグラフにおいて、$(1, y_{n-1}, x_{n-1})$ への最短経路を取る。このパス長が $d$ の時、コスト $d$ 以下の操作列が存在する。

補足: 牛ゲーで、「最短経路が上界に一致」するのと多分同じだと思います。命題の制約が得られた時、それをグラフに起こすと上界が最短経路として得られます。
よって、

命題(操作列 -> パスの対応): 最適解のコスト以下のパス長をもつパスが存在する

補足: 得られた上界が真の値と一致している事を言えば良い訳です。

を言えば良いです。
最適解の状態に対応する様に頂点を遷移していきます。この時、ボールを拾う操作以外は素直な対応が取れます。ボールを拾う操作について、最適解は一番近いやつには拾わせないかもしれませんが、コスト的には一番近いやつに拾わせたとして計算した方が小さいです。以上より成立します。

# お気持ち
問題 $1$ つ $1$ つにこういうことを考えていると時間がものすごく解けます。証明は付属していた方が嬉しいです。"良い"という言葉はカジュアルなので、読み手が十分に意図を理解していないと辛いです。


特に今回構成的かつ過去を改変するちょっと変わった証明をしたわけですが、もっとクリアな議論で示せたり、他に活かせそうなイカした議論が存在すると悲しいです。

# 長い春休み
なんでこんな事を
個人的備忘録：AWS S3とHTMLで画像を簡単に15分で公開する方法を勝手に紹介してみた

## はじめに

AWSのS3バケットを利用して画像をアップロードし、それをHTMLファイル (`index.html`) で表示する方法について解説します。

S3は静的ウェブサイトホスティング機能を提供しており、簡単にウェブサイトを公開することができます。

## **書こうと思ったきっかけ**

最近、クラウドストレージを活用したウェブサイトの構築方法について学ぶ機会がありました。

:::note info
**特に、AWS S3を使った静的サイトホスティングが手軽に実装できる点が魅力的だったため、その手順をまとめてみることにしました。**
:::

また、画像をアップロードし、直接HTMLに組み込む方法についても需要があると感じたため、今回の記事を書こうと思いました。

**詳しくはこちらも参考にしてみてください。**

https://qiita.com/free-honda/items/52729083cac7b1621771

## **1. S3バケットの作成**

### **1.1 AWS S3コンソールにアクセス**
1. AWSコンソールにログインし、「S3」サービスを開きます。
2. 「バケットを作成」ボタンをクリックします。

### **1.2 バケットの設定**
- **バケット名**: 一意の名前を指定（例: `my-image-bucket`）。
- **リージョン**: 任意のリージョンを選択。
- **パブリックアクセスの設定**:
  - 「すべてのパブリックアクセスをブロック」のチェックを外し、公開設定を許可。
- **静的ウェブサイトホスティングの有効化**:
  - 「静的ウェブサイトホスティング」を有効化。
  - 「インデックスドキュメント」に `index.html` を指定。

## **2. 画像をS3にアップロード**

### **2.1 画像ファイルのアップロード**
1. S3バケットを開き、「オブジェクト」タブを選択。
2. 「アップロード」ボタンをクリックし、画像ファイル（例: `my-image.jpg`）をアップロード。
3. アップロード後、オブジェクトのURLをコピーしておく（例: `https://my-image-bucket.s3.amazonaws.com/my-image.jpg`）。

### **2.2 画像のパブリックアクセス設定**
1. アップロードした画像を選択。
2. 「アクセス許可」タブを開く。
3. 「パブリックアクセスを許可」に変更し、保存。

#### S3バケットポリシーの編集

S3バケットのアクセス許可タブに移動し、バケットポリシーを編集します。以下のバケットポリシーを追加します。

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::dev-s3-content/*"
        }
    ]
}
```

このポリシーは、dev-s3-content/* 以下のすべてのオブジェクトに対して、S3からの公開アクセスを許可します。

:::note warn
**Resourceの箇所については、ご自身の環境に合わせて修正してください！**
:::

## **3. index.htmlの作成**

以下の `index.html` を作成し、S3バケットにアップロードします。

```html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>S3にアップロードした画像</title>
</head>
<body>
    <h1>S3にアップロードした画像</h1>
    <img src="https://my-image-bucket.s3.amazonaws.com/my-image.jpg" alt="アップロード画像" width="600">
</body>
</html>
```

**ポイント:**
- `src` 属性に **S3の画像URL** を指定。
- `alt` 属性を適切に設定。

## **4. index.htmlをS3にアップロード**

### **4.1 アップロード手順**
1. S3バケットを開く。
2. 「アップロード」ボタンをクリックし、`index.html` をアップロード。
3. `index.html` のパブリックアクセスを許可。

### **4.2 ウェブサイトのURL確認**
- 「プロパティ」タブの「静的ウェブサイトホスティング」セクションに記載されたURLを確認。
- `https://my-image-bucket.s3-website-ap-northeast-1.amazonaws.com/index.html` などのURLにアクセスして、画像が表示されるか確認。

## **5. カスタムドメインを設定（オプション）**

CloudFrontやRoute 53を使用してカスタムドメインを設定できます。

### **5.1 CloudFrontの設定**
1. AWSコンソールでCloudFrontを開く。
2. 新しいディストリビューションを作成。
3. **オリジンドメイン**にS3バケットのURLを指定。
4. 「オブジェクトのパブリックアクセス」を有効化。
5. CloudFrontのURL（例: `https://d123456789.cloudfront.net/index.html`）を取得。

### **5.2 Route 53でのドメイン設定**
1. Route 53でドメインを取得。
2. CNAMEレコードを作成し、CloudFrontのURLを指定。

## **まとめ**

この方法を使うと、S3バケットに画像をアップロードし、`index.html` を使って簡単に表示できます。

:::note info
***また、CloudFrontやRoute 53を活用することで、カスタムドメインの設定やCDNの最適化も可能です。***
:::

これにより、手軽に静的ウェブサイトを公開し、画像を表示できる環境を構築できます。

## おまけ

こんな感じのイメージになります！

![Screenshot 2025-02-28 at 6.48.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/0b89f9aa-ee79-4ce5-a3f5-5d240920afb3.png)
CentOS7.9からCentOS8へアップグレードする方法(2025年2月版)


# TL;DR
- CentOS7系からCentOS8系へアップグレードしたい(諸事情でElevateをあえて使わずにRHEL8系へアップグレードしたい)
- 2025年2月時点でミラーサイトが消えてしまっているため、vault.centos.orgへURLの変更するなど工夫が必要

# 参考文献
基本的な方法はこちらの記事を参考にして操作します。
https://qiita.com/elect-gombe/items/8ab28fbcaa6aac31424b

# 違うところ
CentOS7.9からCentOS8へアップグレードに関する記事は、多くが5年前の記事となっており、旧系のCentOSのサポートが終了した今、404エラーなどで正常にパッケージがダウンロードできなくなっている。

## レポジトリのURL
dnfでCentOS8系のパッケージを指定する際には、レポジトリなどのURLを現時点でアクセスできるURLに変更する
```
dnf install -y https://vault.centos.org/8.5.2111/BaseOS/x86_64/os/Packages/{centos-linux-repos-8-3.el8.noarch.rpm,centos-gpg-keys-8-3.el8.noarch.rpm,centos-linux-release-8.5-1.2111.el8.noarch.rpm}
```

## .repoファイルの変更
CentOS8系のレポジトリをインストール後に、dnfの各レポジトリについても同様にvault.centos.orgへbaseurlを変更する。(mirrorlistはコメント化)

```/etc/yum.repos.d/CentOS-Linux-BaseOS.repo
#mirrorlist=・・・
baseurl=https://vault.centos.org/$releasever/BaseOS/$basearch/os/
```

```/etc/yum.repos.d/CentOS-Linux-Extras.repo
#mirrorlist=・・・
baseurl=https://vault.centos.org/$releasever/extras/$basearch/os/
```

```/etc/yum.repos.d/CentOS-Linux-AppStream.repo
#mirrorlist=・・・
baseurl=https://vault.centos.org/$releasever/AppStream/$basearch/os/
```

## アップグレードのコマンド
`dnf distro-sync`を実行する時にバージョンもCentOS8の最終バージョン(8.5.2111)を指定する
```
dnf -y --releasever=8.5.2111 --allowerasing --setopt=deltarpm=false distro-sync
```

```
dnf -y install kernel-core --releasever=8.5.2111
dnf -y groupupdate "Core" "Minimal Install"  --releasever=8.5.2111
```

# 備考
- すべての環境下でこの方法によってアップグレード可能であるかどうかは検証していません。依存関係によるエラーは起こる可能性があります。
- 当時から正式なCentOS7からCentOS8へのアップグレードのルートは用意されていません。基本的にはクリーンインストールするか、Elevateを使うべきです。

以上。
Spring Boot 3.2以降におけるNoResourceFoundException仕様変更と404エラー処理の対策

# はじめに

Spring Boot 3.2以降（内部的にはSpring Framework 6.1以降）では、存在しない静的リソースに対するリクエストが処理される際の挙動が変更され、従来の単純な404エラー返却ではなく、`NoResourceFoundException`がスローされるようになりました。  
本記事では、この仕様変更の背景と影響、そして404エラーを正しく返すために採用した**NoResourceFoundException専用のグローバル例外ハンドラー**による対策について解説します。

# 仕様変更の概要

従来、Spring MVCでは存在しないURLへのリクエストに対して、HTTP 404エラーを直接返す処理が行われていました。しかし、Spring Framework 6.1以降、静的リソースの解決時にリソースが見つからなければ、内部で`NoResourceFoundException`がスローされるようになりました。  
この変更はエラー処理の一貫性と柔軟性を向上させるために導入されましたが、既存のグローバル例外ハンドラーがすべての例外（Exception）を一括処理している場合、意図せず500エラーとして扱われるという問題が発生します。

# 問題の背景

- **NoResourceFoundExceptionの仕様変更**  
  Spring Boot 3.2（Spring Framework 6.1）からは、静的リソースが存在しない場合に`ResourceHttpRequestHandler`が`NoResourceFoundException`をスローします。  
- **既存のグローバル例外ハンドラーの影響**  
  アプリケーション内で`@ControllerAdvice`を用いたグローバル例外ハンドラーが`@ExceptionHandler(Exception.class)`などで全例外を一括処理していると、`NoResourceFoundException`もこのハンドラーでキャッチされ、結果としてHTTP 500エラーとなってしまいます。

# 対策：NoResourceFoundException専用のグローバル例外ハンドラーの実装

最も確実な対策は、`NoResourceFoundException`専用のハンドリングを行うことです。以下のような`@ControllerAdvice`クラスを実装することで、存在しない静的リソースへのアクセス時に正しくHTTP 404を返すことが可能になります。

```java
import org.springframework.boot.web.servlet.error.NoResourceFoundException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(NoResourceFoundException.class)
    public ResponseEntity<Object> handleNoResourceFound(NoResourceFoundException ex) {
        // 必要に応じてログ出力やエラーメッセージの加工を行う
        String errorBody = "指定されたリソースが見つかりませんでした。";
        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(errorBody);
    }
}
```

このハンドラーを導入することで、静的リソースが存在しない場合に`NoResourceFoundException`がスローされても、グローバルハンドラーがキャッチし、HTTP 404として適切なレスポンスを返すようになります。

# まとめ

Spring Boot 3.2以降では、静的リソースが見つからない場合に`NoResourceFoundException`がスローされる仕様変更が導入され、既存のグローバル例外ハンドラーで全例外を一括処理していると、本来404とすべきリクエストが500エラーとして扱われるケースが発生します。  
私の場合、デフォルトハンドリング（方法2）やResourceHandlerの優先順位調整（方法3）はうまくいかなかったため、**NoResourceFoundException専用のグローバル例外ハンドラー**を実装する方法で問題を解決しました。  
この方法により、存在しないリソースへのリクエストで正しく404エラーが返されるようになり、ユーザやクローラに対して意図した動作を提供できるようになりました。
読書感想「GitHub CI/CD実践ガイド――持続可能なソフトウェア開発を支えるGitHub Actionsの設計と運用」

# 書籍名「GitHub CI/CD実践ガイド――持続可能なソフトウェア開発を支えるGitHub Actionsの設計と運用」

著者：野村 友規
技術評論社




# 印象に残った部分

## p2ソフトウェアエンジニアの仕事
ソフトウェアエンジニアの仕事は、ソフトウェアを通してユーザに価値を届けることです。
しかし単にコードを書くだけでは価値に届きません。仕事を遂行するには２つの活動です。

1.コードをソフトウェアへ変換し、正しく動作するか検証する。
2.ソフトウェアをユーザが使える状態にする


## p5 CI/CDのメリット
・ユーザの満足度向上
・ビジネス競争力向上
・ソフトウェアエンジニアのクリエイティビティの向上
　CI/CDは問題の発生を促します。問題が大きくなる前に対処すれば、簡単になる。（解決も簡単になる）
・自動化を推し進めることで繰り返し行える作業が大幅に効率化されます。

## p85 自動テストの運用プラクティス
・ユニットテスト中心にする
・チームでテスト設計を学ぶ

## p359 継続的デリバリーの実践
ソフトウェアデリバリーパフォーマンスは高速かつ安全にソフトウェアを届ける能力
・変更リードタイム
・デプロイ頻度
・変更失敗率
・デプロイ失敗時の回復時間

Google DORA(DevOps Research and Assessment)の研究成果
「ソフトウェアデリバリーパフォーマンスは組織パフォーマンスと高い相関がある」

## p361 継続的プラクティスの効果
・非難が少なくオープンは、創造的な文化が浸透している
・デプロイに対する恐怖や予定外の緊急作業が少ない
・組織への帰属意識や、仕事満足度が高い


# 実践できること or 感想

## 感想
・CI/CDは使い勝手の良いスキルだと思いました。
　いろんなプロジェクトに適用しやすいと思いました。

## 実践すること
以下の項目を実際に試してみる。
・２章　Github Action
　　ワークフロー構文 p15
    Github Actionのエラー　p20

・４章 継続的なインテグレーションの実践
  p64 プルリクエストによる継続
  p66 自動テストなインテグレーション

・５章　運用しやすいワークフローの設計
　p95 ロギング
　p99 レポーティング
　p101 チャット通知

・９章　GithubReleaseによるリリース自動化

　p176 9.4 リリースノート作成
　p182 リリースの自動化
ERROR: k8s GDG error public key is not available


- 過去に執筆した記事を日本語に書き写しました
- 翻訳機を使用しているため、誤字や不自然な表現があるかもしれません

# 問題

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3815412/4feebed4-9644-4299-b89e-c77e2c4bd0cb.png)

```Markdown
Hit:1 http://us-central1.gce.archive.ubuntu.com/ubuntu focal InRelease
Hit:2 http://us-central1.gce.archive.ubuntu.com/ubuntu focal-updates InRelease
Hit:3 http://us-central1.gce.archive.ubuntu.com/ubuntu focal-backports InRelease
Hit:4 http://security.ubuntu.com/ubuntu focal-security InRelease
Hit:6 https://download.docker.com/linux/ubuntu focal InRelease
Get:5 https://packages.cloud.google.com/apt kubernetes-xenial InRelease [8993 B]
Err:5 https://packages.cloud.google.com/apt kubernetes-xenial InRelease
  The following signatures couldn't be verified because the public key is not available: NO_PUBKEY B53DC80D13EDEF05
Reading package lists... Done
W: GPG error: https://packages.cloud.google.com/apt kubernetes-xenial InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY B53DC80D13EDEF05
E: The repository 'https://apt.kubernetes.io kubernetes-xenial InRelease' is not signed.
N: Updating from such a repository can't be done securely, and is therefore disabled by default.
N: See apt-secure(8) manpage for repository creation and user configuration details.
root@k8s-worker2:~#
```

# 原因
- KubernetesリポジトリのGPGキーがシステムに存在しないために発生するエラー

# 解決
```Markdown
sudo curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo gpg -o /usr/share/keyrings/kubernetes-archive-keyring.gpg --dearmor
```
- gpg --dearmor を使用してキーをバイナリ形式に変換して保存することにより、APT がリポジトリのパッケージ署名を信頼し検証できるようになります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3815412/9c09a777-24b4-4de4-88cf-6ba05e42b6b3.png)

# レファレンス

https://askubuntu.com/questions/1462497/no-pubkey-error-after-the-key-was-successfully-added

https://minha0220.tistory.com/m/174
Javaメソッド修飾子の順序を探してみました



- 過去に執筆した記事を日本語に書き写しました
- 翻訳機を使用しているため、誤字や不自然な表現があるかもしれません


# はじめに
突然、フィールド宣言における修飾子(modifier)の宣言順序が気になり、調べてみました。

普段、私は習慣として
```java
public static final String test = "hello";
```
と書いていたのですが、突然疑問に思うようになりました。

```java
final static public String test = "hello";
```

こうしても良いのではないかと思い、一度調べてみました。

### Java 17公式ドキュメント
https://docs.oracle.com/javase/specs/jls/se17/jls17.pdf

# 8.4.3 Method Modifiers

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3815412/f459a4aa-97be-4b79-9cf4-bfd4fbb516ec.png)

MethodModifier（メソッド修飾子）のパートには、以下のように記載されています。

> @Anotaition, public, protected, private
abstract static final synchronized native strictfp
If two or more (distinct) method modifiers appear in a method declaration, it is customary,
though not required, that they appear in the order consistent with that shown above in the
production for MethodModifier.

複数の（異なる）メソッド修飾子がメソッド宣言に現れる場合、慣例として（必須ではありませんが）上記のMethodModifier規則で示された順序に従って記述することが望ましいです。


# 推奨事項 
推奨される記述順序は以下の通りです:

- @ Annotation  
- public  
- protected  
- private  
- abstract  
- static  
- final  
- synchronized  
- native  
- strictfp  

上記の順序に従って記述することが望ましいです。
入緑したので

# はじめに
こんにちは、春から情報系高専生のたごころです。実は入茶から約5ヶ月後に入緑していました！
入茶の時より内容がかなり薄いので投稿するか迷いましたが、入水するビジョンが全く見えず、仮にその時が来たとしてもその頃には茶色時代のことを忘れていそうなので、今のうちに供養しておきます。
![スクリーンショット 2025-02-27 23.35.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3870829/fc4302f4-b053-462b-a51e-baca6ebaa133.png)

# 1.実際にやったこと
時系列順に書いていきます
## ☀️夏休み☀️
### 典型90
緑以下の問題は大体埋めました。役に立ったかと言われたら役に立ってるのかもしれないですが、適当に埋めていたのでほとんど忘れてます。今復習+水を埋めるばちゃを走ってますが、「典型でやったやつだー」と感じる問題がほとんどないです。
### D埋め
ABC212以降の問題を埋めていきました。解説見ても理解できない問題や実装だるそうでサボってる問題以外は大体埋めました（よくない）。始めた頃はほとんどの問題を解説ACしていたと思います。今考えると茶〜緑下位は入茶までの知識でほぼ戦えるのでもっと自力ACまで粘る時間を増やしてもよかったなーと思います。

## 10月-12月
### 精選100 
8割以上埋めましたがこの記事を書いている今何をやっていたかほとんど覚えてないです。強いて言うならDPの問題が教育的でDPの理解度が少し上がりました。典型90の方が優先度高いと思います。
### 適当に問題を解く
適当に問題を解いてました。


## ⛄️冬休み⛄️
### ADT
mediumに出てました。
### KUPCの過去問埋め
B問題までしか解けませんでした...


# 2.いろんな大会に出た話
## PCK
学校の部活の先輩と一緒に出ました。4完で普通に本選落ちました。
## JOI
https://x.com/Shupurim/status/1865655397794898275

余裕で本戦落ちました。レートの割に点数低くてほんとに悔しい。
来年こそ本選行って情達やりたい

## 緑以下コンテスト
https://connpass.com/event/331049/

青山学院大学で開催されたオンサイトコンテストに参加しました。結果は4完で茶色コーダーとしてはあまり良くない出来でしたが、Xでの知り合いやつよつよn同世代の人たちと話せたのでとても良い経験になりました。

## KUPC
https://connpass.com/event/337548/

関東在住ですが京都に旅行したかったので、京都大学で開催されたオンサイトコンテストに参加しました。[Reid](https://x.com/kyoupuro)さんと[ohirugohan](https://x.com/ohirugohan_gray)さんとちいかわというチーム名で参加しました。Reidさんに助けてもらって何とかDを解いてひたすら椅子を温めてました...

# 3.結局なにすればいいんですか
**正直茶diffを確実に解けるようになれば緑なれます。** 僕が入緑までに本番通した緑diffは3問しかなく、そのほとんどのコンテストがD茶diffの時のそこそこ早解きよりパフォ低いです。なので茶diffは通せる！という自信がつくまで茶diffをうめてかr、典型90や緑diffの問題を解きに行くといいと思います。

# 4.今後のたごころ
**入水と昨年逃したJOI本選出場を目指します。**
とりあえず
- 典型90を水まで埋める
- DEを水diffまで埋める
- JOIの過去問を埋める

をやりたいのですがこれらを全部こなすのはきつそうですね...
まずはちゃんと寝ろ！

# 5.写真集
入緑から時間経ってるので参考程度に
![スクリーンショット 2025-02-28 0.25.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3870829/8689b310-5635-450e-9124-58f20b786713.png)
![スクリーンショット 2025-02-28 0.26.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3870829/9d756a33-8aa9-4b34-93ba-145d395ae6aa.png)
![スクリーンショット 2025-02-28 2.36.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3870829/9bddd448-fb8c-4b6b-83ff-dd6bf5f1288f.png)
![スクリーンショット 2025-02-28 2.36.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3870829/3865614c-f6d0-4277-a24f-a7b25b15b13f.png)
競プロ日記#25/02/27

# アルゴ式-[間違い探し](https://algo-method.com/tasks/687rPKt)
- 二つの文字列配列（vector<string>）にそれぞれH個の文字列を入れていく
```
int H,W;
    cin >> H >> W;
    vector<string> S(H);
    vector<string> T(H);

    for (int i = 0;i < H;i++){
        cin >> S.at(i);
    }
    for (int i = 0;i < H;i++){
        cin >> T.at(i);
    }
```
- あとはfor文でループさせて[][]でアクセスして比較すれば答えは出せる
```
for (int i = 0;i < H;i++){
        for (int j = 0; j < W;j++){
            if (S[i][j] != T[i][j]){
                count++;
            }
        }
    }

    cout << count << endl;
```
しかし[解説](https://algo-method.com/tasks/687rPKt/editorial)にある通り2次元配列で管理する方法の方が賢い気がする。（柔軟性が高そう）

# アルゴ式-[地図の切り取り](https://algo-method.com/tasks/6726xTm)
- 切り取りの中心を(0,0)として(±1,±1)で表すのが良い

```
for (int i = -1; i < 2;i++){
        for (int j = -1; j < 2;j++){
            cout << map.at(x + i).at(y + j);
        }
        cout << endl;
    }
```
- ちなみに[解説](https://algo-method.com/tasks/6726xTm/editorial)ではfor文にx,yの変数を与えて出力を単純化していた
```
for(int i = x-1; i < x+2; ++i) {
        for(int j = y-1; j < y+2; ++j) {
            cout << S[i][j];
        }
        cout << endl;
    }
```

# アルゴ式-[縦横十字](https://algo-method.com/tasks/840)
- 列が同じマスと行が同じマスをそれぞれp→W、q→Hに対応させて求めていく。
行番号pを固定して列W個分、列番号qを固定して行H個分というイメージ
```
int p,q;
    cin >> p >> q;

    int count = 0;

    for (int i = 0;i < W;i++){
        if (grid.at(p).at(i) == '#'){
            count++; // 横の列
        }
    }

    for (int i = 0;i < H;i++){
        if (grid.at(i).at(q) == '#'){
            count++; // 縦の列
        }
    }
```
- 最後に(p,q)が黒の場合は重複して数え上げてしまうことを考慮
```
 if (grid.at(p).at(q) == '#'){
        count--; // 重複数え上げの分を削除
    }
```
実機のubuntu のパーティションサイズを変更する

## 概要
- ubuntu 用に切っておいたパーティションの容量が足りなくなってきた
- 他に空いているパーティションがあるので、ubuntu を入れ直さずにサイズを追加したい
- ただし、free space が隣接していないので、そのままfree space を割り当てることはできない


## 手順

1.変更前のパーティション構成を`sudo df -h` で調べる

もとの構成
```
Number  Start   End     Size    File system  Name                          Flags
        17.4kB  1049kB  1031kB  Free Space
 1      1049kB  128GB   128GB   fat32        win
 2      128GB   384GB   256GB   ext4         hdd1
 3      384GB   384GB   105MB   fat32        EFI system partition          boot, esp, no_automount
 4      384GB   384GB   16.8MB               Microsoft reserved partition  msftres, no_automount
 5      384GB   511GB   127GB   ntfs         Basic data partition          msftdata
 6      511GB   512GB   849MB   ntfs                                       hidden, diag, no_automount
        512GB   512GB   1384kB  Free Space
```

2.どこのパーティションを追加に用いるか決める
- 今回は windows 用に取っていたパーティションを使うことにした

3.電源オフ
4.Live USB から起動する
5.`sudo gparted`  (インストールされていない場合は `sudo apt-get install gparted` )
6.パーティションの整理
- 今回であれば
    - 1,5,6 を削除
    - 2 を Resize/Move で拡張
    - 保存

7.再起動

## 終わり
パーティションをリサイズできました。めでたしめでたし。
AWSのUbuntuサーバーのDockerでpgAdminを立ち上げたがpgAdminにアクセスできない。。。

# はじめに
- **この記事では先日遭遇したエラーに関しての原因とその解決策を備忘録として残しておきます**。

# 目次
**1. 遭遇したエラーの詳細**
**2. 原因特定の旅**
**3. 原因**
**4. 解決策**

# 遭遇したエラーの詳細
- ある日、**EC2インスタンスのUbuntuサーバーでDockerを使用してpgAdminを立ち上げたのでそこにアクセス**しようとしました。
    しかし、**以下のように「アクセスしています」状態のまま20分ほどアクセスできずにいました**。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3758326/74985677-a561-4741-a1e1-2af9c5551a0c.png)

    これは何かおかしいと感じてエラー発見の旅に出ました。

# 原因特定の旅
- まずはpgAdminをDockerで立ち上げているので以下のコードでDocker関連でエラーが出ていないかログを確認しました。
```bash
docker logs <pgAdminを立ち上げているコンテナ名>
```

すると以下のような出力が得られました。
![スクリーンショット 2025-02-27 213829.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3758326/eafab2b5-9a15-45b6-9522-cdd02266fe84.png)

これは要約すると**Docker側がホスト側（ここではUbuntuサーバーのこと）にpgAdmin用のフォルダを作成したいけど権限がなくてフォルダが作成できない**よ！といわれています。

:::note info
**Linuxでは「UID」という整数でユーザーを管理**しています。
ここで起きている問題としては、ホスト上のフォルダをとあるユーザー（仮にUID = 1000）が所有していて、コンテナ側のプロセスがとあるユーザー（仮にUID=5050）としてファイルに書き込みを試みると、**数値が一致しないため「他人が所有しているフォルダ」となり、書き込み権限を持たない → Permission denied が起きる**、という具合です。
:::

# 原因
- つまり**原因としてはDocker側とホスト側の管理者ユーザーが一致しないことが原因のようなのでそれを一致させてあげればいい**ようです。
::: note warn
**そもそもdocker-compose.ymlファイルの時点で以下のようにこのコンテナのユーザーをルートユーザーと一致させるようにする設定もできる**みたいです。
```bash
user: root
```
**しかし、この方法はセキュリティ的な観点からあまり推奨できるような方法ではありません**。
:::

# 解決策
- **解決策の方向性としてはpgAdminコンテナのユーザーに対して書き込みの権限を与えてあげます**。
    そのために**pgAdminのコンテナのユーザーIDを知る必要がある**のでまずはそのユーザーIDを取得するためのコマンドを打ち込みます。
    ```bash
    docker exec -it <pgadminのコンテナ名> id
    ```

    そして取得したpgadminコンテナのUIDを基にDocker側がファイルを作成しようとしている親フォルダのUIDを変更してあげます。
    ```bash
    sudo chown -R <pgadminのUID>:<pgadminのUID> ./docker/pgadmin
    ```
    そして以下のコマンドを使用して読み書きの権限を付与してあげます。
    ```bash
    sudo chmod -R 770 ./docker/pgadmin
    ```

    ここまで行えばユーザーが一致して正しくpgAdminにアクセスすることができるようになっているはずです。

# まとめ
- この記事ではホスト側とDockerのコンテナ側のUIDを一致させる方法に関してまとめました。個人開発の段階ではあまりUIDを分割する必要性を感じませんが、大規模開発では必要性が高まりそうです。
Unity使ってゲームを作ってみる　その１　プレイヤーの左右移動

# はじめに
仕事が終わった後、何かコードが書きたくなり...
なんとなく興味のあったゲーム制作（未経験）を始めてみることに

とりあえず簡単な処理を書いて、プレイヤーを動かしてみる
素人なのでお粗末な内容でも足からず...

# プレイヤーの左右移動の実装
プレイヤーを A/Dキー（←→キー） で 左右に移動 させる機能を実装する

# 手順
1. プレイヤー（四角い図形）を作成
2. A/Dキー（←→キー）の入力を取得するコードを書く
3. コードをPlayerにアタッチ
4. 動作確認

### 1. プレイヤー（四角い図形）を作成
![スクリーンショット 2025-02-28 1.29.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/257405/23152737-42e7-4792-8fe8-5b8ced383274.png)

2D Object から `Square` を選択し、プレイヤーとして配置


![スクリーンショット 2025-02-28 1.34.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/257405/6d0263f0-58a0-44ec-85c5-66554262b385.png)

この白い四角がPlayer

### 2. A/Dキー（←→キー）の入力を取得するコードを書く
キー入力を検知して、プレイヤーを移動させるスクリプトを作成

```c#:Player.cs
using UnityEngine;

public class Player : MonoBehaviour {
  // 移動スピード
  public float speed = 5f;

  // フレームごとに発火する
  void Update() {
    // A/Dキー or ←→キー
    float move = Input.GetAxis("Horizontal");
    // キャラクターの移動
    transform.position += new Vector3(move * speed * Time.deltaTime, 0, 0);
  }
}
```
- Update()
    - 毎フレーム実行 される（60FPSなら1秒間に60回）
- Input.GetAxis("Horizontal")
    - Aキー or ←キー を押すと -1、Dキー or →キー を押すと 1 を取得
- Time.deltaTime
    - フレームレートに依存せず一定速度で移動

### 3. コードをPlayerにアタッチ
作成したスクリプト Player.cs を Player オブジェクトにアタッチ

![スクリーンショット 2025-02-28 1.39.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/257405/44ab6de0-f9ce-42d8-b57e-484235e49bef.png)

### 4. 動作確認
![move.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/257405/6e35be98-98cd-498e-9376-3c3ca94dd4da.gif)

speedをいじると移動速度も変わる

![move2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/257405/8ec57b08-08f2-4985-95e3-290ff680e0c1.gif)

はい、とりあえず動かせました
これで、プレイヤーの左右移動の実装完了

また機能を追加したらまとめます！
「CloudFront」を「某有名ラーメン店」を例に初学者に説明した話

:::note info
日常での小話です
:::

閲覧頂き、ありがとうございます🙇

## 🕛とある日の出来事

早速本題ですが、
この前メンバーよりこんなことを質問されました。

```
CloudFrontってなんですか？
```

僕の持っている知識をライブドアニュース風に3行要約すると、

```
・オリジンサーバーとエッジサーバーがある
・オリジンにアップしたものをエッジサーバーにキャッシュされる
・アクセスしたユーザーから近いエッジサーバーからキャッシュを提供し高速配信を行なっている
・これがCDNと呼ばれる仕組み😉
```

4行だけどこんな感じでした！
一応ChatGPTにも確認したら概ね合ってるとお墨付き🙆‍♂️

ただその場には**AWS初学者**の方もいたので何かわかりやすい方法が何か模索・・・


## 💡そうだ！蒙古タンメン中本で例えよう！

謎の思いつきですがこんな感じで答えました！

```
・"蒙古タンメン中本"の店舗で食べられるラーメンがオリジンサーバーのコンテンツ
・コンビニで売っている"蒙古タンメン中本"のカップ麺がエッジサーバーからのキャッシュ
・北海道ではXXのコンビニが近くで買えるからいつでもすぐ"蒙古タンメン中本"が食べれるね🍜
```

こんな感じで回答！
一応ChatGPTにも確認したら概ね合ってるとお墨付き🙆‍♂️

さらに簡略説明のため除いていた、「**オリジン負荷軽減**」「**耐障害性**」のところもマッチ🍜

```
・コンビニで買えるから"蒙古タンメン中本"の店舗の行列回避 ≒ オリジン負荷軽減
・"蒙古タンメン中本"がお休みでもコンビニで食べられる ≒ 耐障害性
```

この回答を喰らわしたら、
***イメージ湧いて脳内が痺れました、激辛なだけに*** と1発くらいました👊

## 📝最後に

何か説明する時に日常生活で例えることで、
イメージ湧きやすいのだと改めて実感しました！

**CloudFront**を説明するとこんな説明だけじゃ足りないかもですが、
そのワードを"少し知ってる"のと"知らない"のとでは大違いなので、
イメージだけでも持ってもらえるような説明を頑張ります💪

## ✉️P.S.

この例えにChatGPT君も熱くなってくれましたw
**＞＞＞「蒙古タンメン中本 × CDN」というパワーワード＜＜＜**

![スクリーンショット 2025-02-28 1.29.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130422/4d88afb7-e27a-4c2e-bd61-d7b68e887878.png)
Python3 エンジニア認定実践試験の振り返り

# はじめに
Python3 エンジニア認定実践試験を受験し、合格したの所感や勉強方法を記載します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639400/6349b1f8-587e-471f-803c-c74b5f5de8a9.png)

# 受験当初のPython歴
- 業務歴１年半
- [Python 3 エンジニア認定基礎試験](https://qiita.com/fukuda_0000/items/12c45b26fffc4b2c61c4)の合格歴あり

# 勉強時間
約30時間程度です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639400/794ec807-f79d-4659-88e9-23d4675c3a35.png)

# 勉強方法
### 1. 主教材である「[Python実践レシピ](https://www.amazon.co.jp/dp/4297125765?&linkCode=sl1&tag=network02-22&linkId=780c00a3b4c54f14f793d955a486a1c9&language=ja_JP&ref_=as_li_ss_tl)」の学習
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639400/e137c92f-ddc8-4c88-b390-e927a2269b18.png)

こちらの教材から出題されます。詳しい出題範囲は[こちら](https://www.pythonic-exam.com/exam/jissen)のご覧ください。合格することを目標としていたのでページ数に対して出題率が高いものを重点的に勉強しました。

### 2. [ExamApp](https://python-basic.com/) の利用
Python 3 エンジニア認定基礎試験の際もお世話になりました。
初級・中級・上級とレベル分けがあるので自分の理解度に応じて勉強しました。
主に通勤時間中に利用しました。

### 3. ChatGPTの利用
試験では業務で利用したことのないモジュールについても問われます。
どういった場面で利用するのか質問して、業務にも応用ができるようにChatGPTにどのような場面で利用するか質問しました。

また、モジュールや関数には略称で記載しており覚えにくいものが多数ありました。
その際に、ChatGPTに「正式名称を教えて！」と質問することで、記憶に残るようにしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/639400/d8345eb8-8014-4a25-a6a8-038b64cb7bf1.png)  

### 4. 学習記録をつけること
周知の事実ですが、勉強には学習記録をつけるとモチベーションが長続きすると言われています。
頑張った軌跡が見えるので日々の積み重ねが楽しくなります。
わたしは[Studyplus(スタディプラス)](https://app.studyplus.jp/)を利用しています。

### 5. 効率的な記憶定着方法を学ぶ
社会人になってから、覚えるより調べることのほうが多くなり、学生の頃より記憶力の低下を感じていました。
そこで、どのようにすれば記憶に定着するのか色々調べましたが、下記の動画がシンプルかつ一番わかりやすかったです。

https://youtu.be/DDGVsAWgdYc?si=LrOao2sXUyXazCA0
要約すると、以下大事であるとおっしゃられています。
>アクティブリコール：覚えた内容を能動的に思い出す。
> 反復学習：学習した内容を日を開けて再度学習する

これらを参考にわたしは、下記を行っていました。
- 主教材で学んだことを紙に書き出す。わからなかったことは再度主教材を見て覚える。
- ExamAppで問題をとき、解けなかった問題は数日後に再度挑戦する。

# 受験の所感
主教材の内容をある程度理解していれば、合格できる内容だと思いました。
ただ、高得点を狙いたいのであれば、教材のすみまで覚える必要があります。