OmniAICreator/Qiita-1.07M huggingface dataset:
【不合格体験記】ネットワークスペシャリスト試験(NW)に落ちました(2024/04/21)【R6春】

# 目次
[#1.はじめに](#1はじめに)
[#2.筆者のスペック](#2筆者のスペック)
[#3.学習内容](#3学習内容)
[#4.学習期間](#4学習期間)
[#5.試験](#5試験)
[#6.あとがき](#6あとがき)

# 1.はじめに

題名の通り、ネットワークスペシャリスト試験(NW)に落ちました。

https://twitter.com/ss_IT_study/status/1808700816766951861

来年リベンジしようと思っているので、記録として残しておこうと思います。

# 2.筆者のスペック

* 大学は情報系
* SIerで10年程度勤務
* 情報処理試験だとFE、AP、SCについては取得済み
* SC取得により午前Ⅰについては免除

# 3.学習内容

①[マスタリングTCP/IP―入門編―(第6版)](https://www.amazon.co.jp/%E3%83%9E%E3%82%B9%E3%82%BF%E3%83%AA%E3%83%B3%E3%82%B0TCP-IP%E2%80%95%E5%85%A5%E9%96%80%E7%B7%A8%E2%80%95-%E7%AC%AC6%E7%89%88-%E4%BA%95%E4%B8%8A-%E7%9B%B4%E4%B9%9F/dp/4274224473)

言わずと知れた名著です。
ただ、初見で細かい部分まで読み込むとなかなか進まないので、
まずは流し読みして辞書的に利用していました。

②[左門至峰の出るとこネスペ教科書最短距離で合格できるネットワークスペシャリスト](https://www.amazon.co.jp/%E5%B7%A6%E9%96%80%E8%87%B3%E5%B3%B0%E3%81%AE%E5%87%BA%E3%82%8B%E3%81%A8%E3%81%93%E3%83%8D%E3%82%B9%E3%83%9A%E6%95%99%E7%A7%91%E6%9B%B8-%E6%9C%80%E7%9F%AD%E8%B7%9D%E9%9B%A2%E3%81%A7%E5%90%88%E6%A0%BC%E3%81%A7%E3%81%8D%E3%82%8B%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%B9%E3%83%9A%E3%82%B7%E3%83%A3%E3%83%AA%E3%82%B9%E3%83%88-Usable-Textbook-%E5%B7%A6%E9%96%80/dp/4296203843)

ネスペ界隈では有名な左門氏の参考書です。
①よりもざっくりした内容となっており、導入に関しては最も適した書籍だと思います。


③[ネットワークスペシャリスト過去問道場](https://www.nw-siken.com/nwkakomon.php)

午前Ⅱ対策の定番ですね。
過去問題についてひたすら反復しました。
アカウント登録していたため実績を確認しましたが、最終的な正答率は以下結果です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3324575/a87032be-dacb-9925-f60d-15ab400fce59.png)



④[過去問演習](https://www.ipa.go.jp/shiken/mondai-kaiotu/index.html)

IPA公式から提供されている過去問を3年分実施しました。
①～③のインプットに時間がかかり、午後問題の過去問演習が不足していたところが今回の敗因だと考えています。(3月にAWS SAPの受験を予定していたため、ネスペの勉強開始がかなり遅れてしまいました)
情報処理安全確保支援士試験に合格した時は重点対策を利用して午後対策を体系的に実施していたので、次回受験するときは左門氏の書籍もしくは重点対策を利用しようと思います。


# 4.学習期間
|#|教材|期間　|
|:---|:---|:---|
|1|マスタリングTCP/IP―入門編―(第6版)|14日|
|2|左門至峰の出るとこネスペ教科書最短距離で合格できるネットワークスペシャリスト|7日|
|3|ネットワークスペシャリスト過去問道場|14日|
|4|過去問演習|4日|

# 5.試験


試験の結果としては以下内容でした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3324575/09bf52ba-fa84-b0f3-bfb3-f165bb86f1ae.png)

選択問題は以下です。
午後Ⅰ：問１、問２
午後Ⅱ：問２

試験終了後に各社の解答速報で自己採点はしていましたが、午後Ⅰに関しては概ね自己採点通りの結果でした。
午後Ⅱに関しては自己採点より少し点数が下がり、合格基準点を満たすことができませんでした。
なお、午後Ⅱ問２に関しては問題に不備があり、設問５が全員正解という異例の対応が実施されています。

[令和6年度春期ネットワークスペシャリスト試験 午後Ⅱ 問2 設問5の不備とその対応について](https://www.ipa.go.jp/news/2024/shiken_20240607.html)

各所で逆下駄、配点1点での正解等噂されていますが、元々IPAの情報処理試験は配点が開示されておらず、偏差値的に合格率を維持している可能性も高いです。
今回の受験者の中で合格に足る解答ができなかったのは事実なので、
切り替えて来年リベンジしようと思います。

# 6.あとがき
ネットワークスペシャリスト試験(NW)の不合格体験記でした。
秋期試験はPMを受けようと思っていましたが、
来年のNWに向けて学習したいという点とAWS認定も頑張りたいという点から、
まだ決めかねている状況です。
今月ゆっくり悩んで今後のスキルアップの計画を見直そうと思います。
自己紹介ページ　画像をじわりと表示させる

お疲れ様です。

昨日少しお話しいたしました、自己紹介ページで使っている画像を、JSを使ってじわりと表示させるよう編集をしてきました。

![js.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3810013/f86dea22-f7d8-15ee-bd9e-364ec4552ec0.png)
![スクリーンショット 2024-07-04 221212.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3810013/18f21568-6d64-da2c-4624-5cab14c1aac5.png)

skyというid名の画像が現れたら、コンソールに「あおぞら」と返すようにします。
ページをスクロールし、画像を表示させると…　↓
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3810013/72f2249d-1287-70a9-85f3-e14176065ed0.png)
カウントが増え、監視できていることが確認できました！
これが IntersectionObserver なのですね…！
初めて使いました。

とりあえず、コードを映し書きしながらMDN先生で IntersectionObserver のことを調べたりしながら編集し、やりたかったことができました。
![js2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3810013/f9cd8a18-23ac-630b-38e5-da71016851f0.png)

画像が現れた直後　↓
![before.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3810013/6bd8abc9-8ea8-c599-5a26-0881c9c7d11c.png)

3秒後　↓
![arter.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3810013/3b8239df-e7ca-86b3-7faa-be485343b13b.png)
opacity を使って不可視から可視状態になりました！
<br>
本:book:では、
**traslate: ['200px 0', 0],**
となっており、画像が右から左に移動しながら、現れるようになっておりましたが、移動はさせずにその場でじわりと現れるようにしました。
translate についてもよく知らなかったため、MDN内で検索しましたところ、[]の数値はx、y、z軸まで指定ができるということも知ることができました。3Dの平行移動も可能とのことです。

初めて使った値もありましたので、このあと自分の言葉でまとめようと思います:sweat_smile:

<br>
リンクの貼り方が分かったので、昨日紹介しました本です　↓

![スクリーンショット 2024-07-04 231241.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3810013/75e2984f-7b03-b5b5-1cd5-951945ab00c9.png)

[1冊ですべて身につくJavaScript 入門講座](https://www.amazon.co.jp/%E3%80%90Amazon-co-jp-%E9%99%90%E5%AE%9A%E3%80%911%E5%86%8A%E3%81%A7%E3%81%99%E3%81%B9%E3%81%A6%E8%BA%AB%E3%81%AB%E3%81%A4%E3%81%8FJavaScript%E5%85%A5%E9%96%80%E8%AC%9B%E5%BA%A7-DL%E7%89%B9%E5%85%B8-JavaScript%E3%83%81%E3%83%BC%E3%83%88%E3%82%B7%E3%83%BC%E3%83%88-%EF%BC%91%E5%86%8A%E3%81%A7%E3%81%99%E3%81%B9%E3%81%A6%E8%BA%AB%E3%81%AB%E3%81%A4%E3%81%8F/dp/4815615756/ref=sr_1_5?crid=1WEX035GO11WH&dib=eyJ2IjoiMSJ9.HOn9nQGoszM8GYEcVoUJfQsKex-suLTbIHORoyslCcg4vM1CK4Z5Zxgg1VpqBwqyQgVkvCdpKYqOUePV4GxK28NbcWHW-3-3bYBJrv5C00KTBiMdOPT2A6fmP0F6welzpXrVTjF5v32ELPsDySvCB1Wa7U9eOKpC6rV7BviLue6uoKELmATYaip5_uFw2EWCW-j_9tNPMeHecDQFMbmC6BWzJ3zT9-mQeC6dMbvJEi6i60CevdeFlC1eivsur2wJZDw4MPLJMcYSpOhXOSuv2n4LOhKaYiFGFsvLdp4ZwUc.zRuABOuZbaTg8sjoIZ9Bm0-wemQCfiX30W-UU3Ni17o&dib_tag=se&keywords=javascript+%E5%85%A5%E9%96%80&qid=1720101980&sprefix=%2Caps%2C195&sr=8-5)
投稿 4 標準入力

本日の勉強時間　８H


①「配列linesを定義」
②で「入力値を配列linesに追加（push）」
③で「入力された値を出力する」

例えば、入力されるのが   "text"なら、配列linesの０番目
に追加されるという感じです。
それを👈③でconsole.logで出力

https://qiita.com/cotton11aq/items/a8b93d61fca8f83ffaae
ドキュメント系の個人的メモ📝

# 目次
[気を付けること](#気を付けること)
[やらかしたこと](#やらかしたこと)
[機能仕様書](#機能仕様書)

# 気を付けること
- Excelファイルの場合、「ファイルタブ」から、最初にそのファイルを作成した人が分かる
→他社宛の資料を作成した場合、そこもチェックする！！
(他社に渡す資料なのに、ファイル作成者がそのプロジェクトに関わっていない人とかだと「ん？(´◉ω◉` )」となってしまう)
- 他社のExcelファイルを流用したりすると、作成者が他社の人になっていたりするため、客先に提出する資料は、その辺も気をつける
- 注記が備考の扱いなら、二重記述とならないように注意
- 作業中(下書き状態、未完成)のものは、タイトルとかに[WIP]と書いておくと、わかりやすい

https://www.weblio.jp/content/WIP
> 「WIP」とは、進行中・作業中・仕掛品・作りかけのもの・やりかけのもののことを意味する表現。

# やらかしたこと
## 二重記述
- 二重記述になっている例
表に「備考」があるのに、表の下にも表の内容についての「備考」がある↓
![2025-03-31_00h56_34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2330584/e8d13423-7649-49c7-8fbc-69014864cb3b.png)
- 表の備考欄に同じ内容を繰り返し書くのも微妙なため、備考欄には「※」や「※1」と記載して、表の下に注記(「※」や「※1」の内容)を書く

|NG例 |OK例  |
|---|---|
|![2025-03-31_00h59_21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2330584/b4e22a16-623a-4f62-8aea-e5d057155535.png)| ![2025-03-31_00h59_30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2330584/26356615-8f24-46db-a47c-983fe2657aff.png)|
- 「※」「※1」←コレが**注記**
→そのため、わざわざ表の下に見出しとかで「注記」と書かなくて良い

|NG例 |OK例  |
|---|---|
|![2025-03-31_01h01_00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2330584/694ef3b2-adb6-4a4d-b07d-6971f8237bc0.png)|![2025-03-31_01h01_05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2330584/a8b0d6da-79bd-461c-9839-147ab2d9306d.png)|



# 機能仕様書


https://qiita.com/pe-pe-desu/items/c04e7f5f76f7375d5ee5
MySQLのバージョン決め

MySQLのバージョンは8.4で作ってみる。

1. [5.7系は2023年10月21日にEOL](https://qiita.com/akagane99/items/1469f98a906245d403ac)
2. [ちょうど2024年4月30日にLTS（Long Term Support）のMySQL 8.4.0がリリースされた。](https://dev.mysql.com/doc/relnotes/mysql/8.4/en/)

exposedで作るので、固有の機能はそれほど使わないだろうけれど。
AWS備忘録（Lambda関数の使い所）

AWS Lambdaとは…
・サーバレスコンピューティングで、プログラムのコードを実行できるフルマネージドサービスのこと。Lambda関数という実行コードを使用する。
・開発言語はJava、Node.js、Pythonなどに対応。
・実行時間は最長で15分。
・料金＝リクエスト数ベースの課金＋実行時間ベースの課金。
・実行タイミングは特定のイベントをトリガーとする。

サーバレスとは…
・サーバーを必要としない、リクエスト発生時のみプログラムが実行されるアーキテクチャで、インフラの管理はAWSが行う。

【メリット】ずばり、プログラム開発に集中できる！
・プログラム実行環境の構築や運用が不要になり、負荷が軽減される
・プログラムはリージョン内の複数のAZに分散して配置されるため、耐障害性・可用性の向上
・プログラムへのリクエスト数に応じたスケーリングが自動的に行われることにより、拡張性向上


【使用用途例】
・トリガーでファイル・データ処理を行う
・ユーザーのアクセス時にユーザー認証を行わせる
・ルーティーン処理を実行する（EventBridge）
・バッチ処理として使用する（StepFunction）

【トリガー例】
・Amazon EventBridgeによる通知
・Amazon S3バケットにオブジェクトが作成された時
・Amazon DynamoDBのテーブルに変更があった時
・Amazon SQSのキューにメッセージが追加された時
・Amazon SNSからトピックが通知された時
・Amazon API Gateway経由で直接Lambda関数が呼び出された時

例えば、ユーザーからアップロードされた画像ファイルがS3バケットに保存（オブジェクトが作成）された時に、Lambda関数が実行されて画像ファイルの情報をDynamoDBに書き込むといった利用方法があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/608098/981da8fe-6c42-2c3a-472b-128b684c05e0.png)
文字列の特定文字での分割、配列/Listの連結（string.Splitとstring.Joinの使い方）

## 0.0 　はじめに
string.Splitをつかうと、文字列を指定した文字で分割することができます。
string.Joinは配列やListの要素を連結してくれます。配列をログに出す時などに使うと便利です。

## 1.0 　String.Splitでの文字列の分割

```C# Test.cs
// 文字列の定義
string momotaro = "おじいさんは、やまに、しばかりに、いきました。";
        
// 文字列を特定文字で分割する（ここでは 「、」）
// 分割した文字列は配列に代入
string[] strArray = momotaro.Split('、');

// 分割した文字列を1文づつコンソールに表示
for (int i = 0; i < strArray.Length; i++) {
    Debug.Log(strArray[i]);
}

```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352037/e2768951-4370-3834-1dfd-6b6b60ef3366.png)







## 1.1 　2つ以上の文字での分割
2つ以上の文字での分割も可能です。
char[] splitChar = {'、', '。'};のように分割に使用する文字を定義
momotaro.Split(splitChar);
（「、」もしくは「。」のどちらかで分割する）






## 2.0 　String.Joinでの文字列の連結

```C# Test.cs
// 数字の羅列（文字列）を定義
string suji = "0,1,2,3,4";

// 文字列を特定文字で分割する（ここでは 「,」）
// 分割した文字列は配列に代入
string[] strArray = suji.Split(',');

// 分割した数字を1文字づつコンソールに表示
for (int i = 0; i < strArray.Length; i++) {
    Debug.Log(strArray[i]);
}

// 数字を1行で表示
// " と "で文字列（数字）を連結
Debug.Log(string.Join(" と ", strArray));


// おまけ
// 数字（int）の格納用
List<int> intList = new List<int>();
        
// 文字列(string)を数字（int）に変換
for (int i = 0; i < strArray.Length; i++) {
    intList.Add(int.Parse(strArray[i]));
}

// 変換した数字のはListを1行で表示
Debug.Log(string.Join(" + ", intList));

// 数字の合計
int sum = 0;
for (int i = 0; i < intList.Count; i++) {
    sum += intList[i];
}
 Debug.Log("数字の合計は " + sum + " です。");

```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352037/fdd49af1-b3ec-0efd-2b26-293071895248.png)
CloudFlareにデプロイするためのRemixプロジェクト ページング処理のためのクエリパラメーターを追加

## 概要

Remixアプリケーションでページング処理を追加してみる。

## 前提

下記の内容が完了していること。

https://qiita.com/miriwo/items/f6619ceeb771fac5645a

## 方法

1ページあたり5件タスクが表示されるように変更してみる。

1. 下記の内容を`app/routes/tasks-loader.ts`に追記

    ```app/routes/tasks-loader.ts
    const page: number = Number(searchParams.get("page")) || 1; // 設定されていなかったらデフォルト値の1を設定
    const pageSize: number = 5; // 1ページあたりの表示数

    // findManyを使ったデータ取得処理の中に下記を追加
    skip: (page - 1) * pageSize, // スキップするレコード数
    take: pageSize, // 取得するレコード数
    ```

1. `app/routes/tasks-loader.ts`の全体は下記のようになった

    ```app/routes/tasks-loader.ts
    import type { LoaderFunctionArgs } from "@remix-run/cloudflare";
    
    export const loader = async ({ context, request }: LoaderFunctionArgs) => {
      const url = new URL(request.url);
      const searchParams = url.searchParams;
    
      const isCompleteParam: unknown = searchParams.get("isComplete");
      const isComplete: boolean = isCompleteParam === "true" ? true : false;
    
      const isDeletedParam: unknown = searchParams.get("isDeleted");
      const isDeleted: boolean = isDeletedParam === "true" ? true : false;
    
      const taskCategoryMasterIdParams: string[] = searchParams.getAll("taskCategoryMasterId");
      const taskCategoryMasterIds: number[] = taskCategoryMasterIdParams.map(id => Number(id));
    
      const page: number = Number(searchParams.get("page")) || 1; // 設定されていなかったらデフォルト値の1を設定
      const pageSize: number = 5; // 1ページあたりの表示数
    
      const isTrue = 1; // フラグONの意味 マジックナンバー申し訳ない。。
    
      try {
        const tasks = await context.db.tasks.findMany({
          where: {
            ...(isComplete && { is_complete: isTrue }),
            ...(isDeleted && { deleted_at: {not: null}}),
            ...(taskCategoryMasterIds.length > 0 && { task_category_master_id: { in: taskCategoryMasterIds } }),
          },
          include: {
            task_category_master: true, // schema.prismaで定義したリレーションを指定
          },
          skip: (page - 1) * pageSize, // スキップするレコード数
          take: pageSize, // 取得するレコード数
        });
        return tasks;
      } catch (error) {
        console.error("Failed to load tasks:", error);
        throw new Response("Internal Server Error", { status: 500 });
      }
    }
    ```

1. この状態で`/tasks`にアクセスしてみると最初の5件だけタスクが表示される
1. `/tasks?page=2`にアクセスすると次の5件のタスクが表示される
CentOSで使っていたcronのファイルをUbuntuに持ってきたら動かなくなった

CentOSで動いているサーバーで使っていたCronの設定ファイルを再利用しようとして、そのままUbuntuで動いているサーバーに転送したのだけれど、全く動いている気配がない。

いったいどういう事ですか……？と最近なったので、メモを残しておく。

## 事象
CentOSサーバーで`/etc/cron.d`配下に`hogehoge-1.0.0` みたいな名前のcronの設定ファイルを置いていて、Ubuntuサーバーにも同様に配置した。

Cronの実行時間になっても全く実行されている気配がなく、ログも出ていなかった。

## 原因

結論としては、ファイル名がいけないようだった。

なんとなくファイル名のドットが怪しい気がして、ファイル名を `hogehoge` にリネームしたところ、問題なく実行された。

一旦動いたものの、なんだか腑におちず、Ubuntuでは .（ドット） が使えないのかな？と思って調べていたら、以下のスレッドを発見した。
https://bugs.launchpad.net/ubuntu/+source/cron/+bug/706565

どうもUbuntuのcronは`run-parts`コマンドを利用して動かしているらしく、スレッドによると`run-parts` コマンドの制約に従う必要があるらしい。

`run-parts`コマンドのマニュアルを見てみると、ファイル名の制約が書いてあった。
https://manpages.ubuntu.com/manpages/noble/man8/run-parts.8.html

> If neither the --lsbsysinit option nor the --regex option is given  then  the  names  must
       consist  entirely of ASCII upper- and lower-case letters, ASCII digits, ASCII underscores,
       and ASCII minus-hyphens.

つまり、この4つの文字しか使えないらしい。
* アルファベット（大文字・小文字）
* 数字
* アンダースコア（ _ ）
* ハイフン（ - ）

で、ファイル名にドットを入れていたものは動かないと………………。そうですか………。
さっきまで（CentOSのサーバー上で）は動いてたじゃん😭

ちなみに、かなり丁寧にまとめてくれていた以下の記事を後から読んだ。
先に読みたかった……！でも先に読んでたら苦労してないから忘れてただろうな……。

https://tech.quickguard.jp/posts/etc-cron-debian-specific/
新人エンジニア　DP-203 - Data Engineering on Microsoft Azure 受験体験記編

## この記事のまとめ
この記事では以下のことを紹介しています
- 試験登録方法
- おすすめの勉強教材
- 受験日に失敗した話


## はじめに
こんにちは、皆さん。今回は、初めてのAzure資格試験に挑戦した体験を共有したいと思います。私は初心者であり、至らない点もあるかもしれませんが、温かく見守っていただければ幸いです。

この記事では、試験に臨む際の注意点や、実際に試験を受けて感じたことを詳しく紹介します。さらに、試験に合格した際の体験もお伝えしますので、ご参考にしてください。

【試験合格体験】試験当日は予想外の問題も出題されましたが、事前にしっかりと準備をしていたため、自信を持って対応することができました。特に重要だったのは、実務での経験が理論だけでなく実践で役立ったことです。また、試験中にはMicrosoft Learnなどのリソースも活用しましたが、試験前に時間を十分に取ることが成功の鍵でした。

これから試験を考えている方々にとって、この記事が参考になれば幸いです。ご質問やご感想がありましたら、コメントでお知らせください。一緒に学び合い、成長していきましょう

これから受験を考えている方々の参考になれば嬉しいです。それでは、さっそく始めましょう！

## 受験登録方法
1. Microsoftのアカウント作成
1. 公式ページから試験を選択
1. 試験日を決める
1. 試験料の支払い
### アカウント作成
https://account.microsoft.com/account?lang=ja-jp

上記のサイトからアカウント作成してください。

### 公式ホームページから試験の選択
https://learn.microsoft.com/ja-jp/credentials/browse/

上記のサイトから目的の試験を選択します。「Data Engineering on Microsoft Azure」の場合は、ロールをデータエンジニア、レベルを中級、資格の種類を認定資格に選択すると、一番上に表示されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3647606/ca6d8500-11b2-b748-4e63-b9133c5b591b.png)

### 試験日を決める
試験を登録すると、onVueで試験日を登録することになりました。私は自宅で試験を受けることを選択しました。

試験の受験日は、土日から埋まっていくので、土日に受けたい場合は早めに登録しましょう！6月の初めに試験を登録したときには、6月の土日は1日も空いていませんでした。
※私は仕事の予定を調整して平日の午前中に試験を受けました。

### 受験料の支払い
2024年6月時点では、税込み23,212円でした。
円安の影響もあり、新人エンジニアには辛い金額でした…

## 試験の勉強
### 前提知識
仕事の関係で、Azureのサービスを約6か月触っており、Azureについて最低限のサービスは知っていました。これから紹介する勉強方法は、上記の前提をもとにしたおすすめの勉強内容です。

## 勉強１: Microsoft Learn
https://learn.microsoft.com/ja-jp/training/

公式サイトで最低限の知識を習得しました。
仕事で触ることもあったので、私は関係ありそうなサービスをネットサーフィンした程度です。

## 勉強２：　Udemy
自分が利用した講座は下の２つです。

https://www.udemy.com/course/azure-data-engineer-practice-sets/learn/quiz/6146486#content

https://www.udemy.com/course/azure-data-engineer-practice-sets/learn/quiz/6146486#content

主に試験の方式に慣れるため、上記の2講座を受講しました。講座の使い方としては、繰り返し何度も解くことをしました。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3647606/493e3838-fc1f-8568-005c-1c04c12bff89.png)

写真のように何度も解くことで、点数が上がっていきました！ただ、6/16のように不合格になることもあるのでご了承ください…

## 受験日当日
自分の失敗談を２つ紹介しておきます！
これから受験する皆さんは、以下の２点に気をつけてください

### 注意点１：受験環境
まず、試験で焦った点は、ネットワークです。試験の前日まで問題なかったネットワークの速度（ダウンロード速度）が突然遅くなり、試験の準備が進められない状況に陥りました。

焦って調べた結果、wifiを再起動することで問題が解決することが分かりました！
※wifiの再起動がネットワーク速度の改善につながる根本的な原因は、新人エンジニアには難しいので説明を省略します。

具体的な手順は以下の通りです：

1. wifiの電源を抜く
1. 5〜10分待つ
1. wifiの電源を入れる
これで問題が解決しました！

試験を受ける方は、試験時間に余裕を持って試験に臨み、同じような状況が発生しても余裕を持ってwifiを再起動できるように準備しましょう！

### 注意点2: 試験方式
自分の調査不足のため、試験中にMicrosoft Learnで調べても良いことが、試験が開始してから判明しました。

他の試験でも調べられるかは不明ですが、最低限この試験では調べることができるということを確認して試験に臨んで、私のように試験開始時に焦らないようにしてくださいorz


## 最後に
最後まで読んでいただき、ありがとうございました。この記事が少しでも皆さんのお役に立てたなら嬉しいです。

Azureの資格試験は決して簡単ではありませんが、努力と準備次第で必ず合格できます。受験を考えている皆さん、どうか諦めずに頑張ってください。私も応援しています！

質問や感想がありましたら、コメント欄にぜひお寄せください。一緒に学び合い、成長していきましょう。これからも皆さんの成功を心から願っています
BFSを用いた硬貨の組み合わせ問題の解決方法

# BFS（幅優先探索）の簡単な説明
幅優先探索（BFS：Breadth-First Search）は、グラフやツリーなどのデータ構造を探索するためのアルゴリズムの一つです。BFSは、開始ノードから近いノードから順に、同じレベルのノードをすべて探索してから次のレベルに進むという方法で動作します。BFSは通常、キュー（FIFO）を使用して実装されます。

BFSの主な特長は以下の通りです：
1. 最短経路探索：BFSは無加重グラフでの最短経路探索に適しています。最初に到達した解が最短であることが保証されます。
2. レベル順探索：BFSはノードをレベル順に探索するため、ノード間の距離を簡単に把握できます。

# 問題の解法の説明
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3824062/2805f5f2-63c8-39e5-b437-63f74390ea0c.png)

以下は、与えられたシングルリンクリストを0を基準に値をマージする問題の解法をBFSを用いて説明したものです。

問題説明
- 入力：異なる額面の硬貨を表す配列 coins と総額 amount
- 出力：指定された金額を作るために必要な最小の硬貨の数。もしその金額を作ることができない場合は -1 を返す。

**制約条件**
- 1 <= coins.length <= 12
- 1 <= coins[i] <= 2^31 - 1
- 0 <= amount <= 10^4

## 改善されたBFSコード（Setを使用した訪問チェック）

``` java
import java.util.*;

class Solution {
    public int coinChange(int[] coins, int amount) {
        if(amount == 0) return 0;
        
        // 訪問チェックを行うためのセット
        Set<Integer> visited = new HashSet<>();
        Queue<Node> que = new LinkedList<>();
        
        // キューの初期化
        for(int coin : coins){
            if (coin <= amount) {
                que.add(new Node(coin, 1));
                visited.add(coin);
            }
        }
        
        int res = Integer.MAX_VALUE;
        
        while(!que.isEmpty()){
            Node current = que.poll();
            
            if(current.sum == amount){
                res = Math.min(res, current.count);
                break;
            }
            
            for(int coin : coins){
                int newSum = current.sum + coin;
                if(newSum > amount) continue;
                
                if (!visited.contains(newSum)) {
                    que.add(new Node(newSum, current.count + 1));
                    visited.add(newSum);
                }
            }
        }
        
        return res == Integer.MAX_VALUE ? -1 : res;
    }
}

class Node {
    public int sum;
    public int count;

    Node(int sum, int count){
        this.sum = sum;
        this.count = count;
    }
}

```

## コードの説明
1. 入力検証：
    - amountが0であれば、硬貨は必要ないため0を返します。

2. 訪問チェックのためのSetの初期化：
    - Set<Integer> visited = new HashSet<>();を使用して、各金額に対して訪問したかどうかを追跡します。

3. キューの初期化：
    - 各硬貨を使用して初期キューを設定します。金額が amount 以下の硬貨のみをキューに追加し、訪問チェックセットに追加します。

4. BFS探索：
    - キューが空になるまでノードを探索します。
    - 現在のノードの金額が目標金額と等しければ、結果を更新し探索を終了します。
    - 各硬貨を使用して新しい金額を計算し、訪問していない金額であればキューに追加し、訪問チェックセットに追加します。

5. 結果の返却：
    - 結果が初期値のままであれば、目標金額を作成できないため -1 を返します。それ以外の場合は結果を返します。

## BFSアプローチの利点と注意点

利点：
    - 最短経路探索：BFSは最短経路を見つけるのに適しています。問題の解が最短であることを保証します。
    - 全ての可能性を探索：全ての可能な経路を一度に広げて探索するため、最適解を見つけやすい。

注意点：
    - メモリ使用量：BFSは多くのノードを一時的にメモリに保持する必要があるため、大きな探索空間ではメモリ使用量が増加します。
    - タイムアウト：探索空間が大きい場合、タイムアウトが発生する可能性があります。適切な最適化が必要です。


# Summary
上記のコードはSetを使用して訪問チェックを行うことで、メモリ効率を高め、探索の重複を避けています。
繰り返される値をキャッシングすることが重要だった問題でした。
Pythonで簡単に欠損値解析！missingnoライブラリの使い方

データ解析で避けて通れないのが欠損値の問題。今回は、Pythonのmissingnoライブラリを使って、データセットの欠損値を可視化する方法を紹介します。Kaggleのタイタニックデータセットを例に取り、具体的な使い方を解説します。

# 欠損値の種類
- MCAR（完全にランダムに欠損）
- MAR（条件付きでランダムに欠損）
- MNAR（ランダムでない欠損）

# データの準備
kaggleのtitanicデータを使用して可視化してみます。まずはライブラリをインポートし、データを読み込みます。

:::note info
titanicのデータはkaggleから予めダウンロードしています(ファイル名:train.csv)
:::


```python
#ライブラリのインポート
import pandas as pd
import missingno as msno

#データをロード
train=pd.read_csv('train.csv')
train.head()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3768377/f3777ee2-707c-baf0-dd8c-dc0c4ca6483a.png)



# 可視化の方法
## バーグラフ：全体の欠損状況を一目で把握。
```python
import missingno as msno
msno.bar(df)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3768377/27f166b0-e50a-b802-97b6-3653045fa16c.png)

## マトリックス：データのパターンを視覚化。

```python
msno.matrix(df)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3768377/2743aff7-cf3a-cc8f-0701-4d587e3bd352.png)

## デンドログラム：変数間の相関を見つける。
```python
msno.dendrogram(df)
```  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3768377/1f3e6aaa-ce75-24cb-24d5-b10a6a4d6d6f.png)

## ヒートマップ：欠損値の相関関係を把握。

```python
msno.heatmap(df)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3768377/5f193eb6-5e30-292f-aeb4-0a27f2572f79.png)

# まとめ
欠損値の可視化により、データの前処理がスムーズに進み、解析の精度が向上します。missingnoライブラリを活用して、欠損データのパターンを理解し、より良いデータ解析を目指しましょう！
Google Cloudに初めて触った話

先日Google Cloud上でサーバーを初めて構築しました。
普段はAWSなどを中心に利用しているので、そちらとの違いなど引っかかった点を記載していこうと思います。
（詳細は個別記事にする予定なので、本記事自体は記録程度に）

## 構築要件
・アプリ実行用のサーバーを1台用意する
・将来の拡張を見越してLoad Balancerを用意する
・アクセス時にIP制限をする
・定期的にアプリ上で作成したファイルを外部ストレージに保管する
・日次バックアップを取得する
・CPU監視を行い、異常時にはメールを飛ばす

## 実際の構成
![構成図例#01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2969669/0659240a-4b5d-ec78-1d80-e8a7b765c951.png)

上記の構成図は[Google Cloud純正のツール](https://googlecloudcheatsheet.withgoogle.com/architecture)で作成しました。

## 構築時に悩んだ点・AWSとの違いを感じた部分など
#### ①プロジェクト・組織の考え方
まずGoogleアカウントの発行から始めたのですが、法人に紐づくかどうかなど何個か引っかかりそうなチェックポイントがありました。
また、組織という概念もなかなか難しかったです。今回は検証目的での利用がメインだったので使いませんでしたが、最初からきちんと考慮しつつ構築していった方がよさそうです。

#### ②権限の振り方
権限の振り方が難しかったです。○○開発者権限だと足りなくて管理者を入れたり、それでもだめ、といったトライ&エラーを繰り返しました。
構築初期はわからな過ぎて「編集者」を使ったりもしていました。
正直ここは何とかして欲しいです、

#### ③ネットワークの考え方
AWSのdefaultと同じようなものがあるので最初はずっとそれを使っていました。
ただ、defaultだとIP制限の設定などがゆるゆるなので、慣れてきたらきちんと自分で設定しないといけないです。
ここはAWSのVPCとかと似ているので、慣れてくれば簡単に出来るようになりそうです。
ただ、VPCとリージョンの考え方がAWSとは異なるので、ここは間違えないようにしないといけなそうです。

#### ④ロードバランサーの利用方法
ロードバランサーを構築としたとき、選択できるロードバランサーの種類の多さに驚きました。
[公式の図](https://cloud.google.com/load-balancing/docs/choosing-load-balancer?hl=ja)が分かりやすかったですが、用途（ALB/NLB）・内部/外部・グローバル/リージョンなどで分かれており合計で10種類もあります。
10種類と聞くと適切なものを選択できるのか？と不安になりましたが、UIで作りたいものに誘導してくれるので、案外悩まずに作れました。

ただ、今回実施したかったSSLオフロードの設定ですが、ポータル上では完結できずCLIでしか設定できませんでした。これは私の方でよい方法を見つけきれてないかもしれないので、もう少し調べてみたいと思います。

また、ヘルスチェックの際もIP許可を入れないといけなかったりとつまずくポイントが複数あったので、こちらもブログ記事にしたいと思います。

#### ⑤日本語表記
十分許容範囲ではありますが、ときどき日本語表記が怪しい箇所がありました。なので、標準言語を英語にして構築したほうが安全かもしれないです。
(IBMCloudとかと比較したら全く苦にはなりませんが)

## Google Cloud触った感想
AWSと比較するとそもそも存在しない機能もあったりと、まだまだな部分もあります。ただ、全体的にはかなり使いやすい、というのが第一印象です。
また、ドキュメントも分かりやすくまとまっているのも好感度が高いです。
今後の成長も含め、今のうちからGoogle Cloudについては慣れておきたいともいます。
Adobe Illustratorで印刷入稿前のチェックの効率化を図る自動化スクリプト

## はじめに

Adobe Illustratorで作業を自動化するためのスクリプト(JavaScript)を紹介します。このスクリプトは、印刷入稿前のチェックの効率化を図るために、以下の一連の操作を自動で実行します。

## 機能
このスクリプトは次の操作を自動で行います：

1. 全てのレイヤーとオブジェクトのロック解除 - 編集が困難なロック状態を解除します。
1. カラーモードの変換 - ドキュメントがRGBモードの場合、プリント基準のCMYKモードへ変換します。
1. テキストのアウトライン化 - フォント依存の問題を避けるため、全てのテキストをアウトライン化します。
1. リンクファイルの埋め込み - 外部リンクされている画像やデータをドキュメントに埋め込みます。
1. ファイル名の自動改名 - ファイル名の末尾に「(CHK)」を追加し、バージョン管理を容易にします。
1. AIとPDF形式での保存 - 編集可能なAIファイルと共有・印刷向けのPDFファイルの両方で保存します。

## メリット
このスクリプトにより、以下のようなメリットがあります：

- 時間の節約：複数の手動操作を一度に実行することで、時間を大幅に節約できます。
- エラーの削減：手動での操作ミスを防ぎ、一貫した出力を保証します。
- 作業の標準化：ファイルの保存形式や編集プロセスを標準化し、チーム間での共有が容易になります。

```diff_javascript
#target illustrator

function unlockAll(doc) {
    for (var i = 0; i < doc.layers.length; i++) {
        var layer = doc.layers[i];
        layer.locked = false;
        unlockItems(layer.pageItems);
    }
}

function unlockItems(items) {
    for (var i = 0; i < items.length; i++) {
        items[i].locked = false;
        if (items[i].typename == 'GroupItem') {
            unlockItems(items[i].pageItems);
        }
    }
}

function convertToCMYK(doc) {
    if (doc.documentColorSpace !== DocumentColorSpace.CMYK) {
        app.executeMenuCommand('doc-color-cmyk');
    }
}

function createOutlines(doc) {
    for (var i = 0; i < doc.textFrames.length; i++) {
        var textFrame = doc.textFrames[i];
        textFrame.createOutline();
    }
}

function embedLinkedFiles(doc) {
    var placedItems = doc.placedItems;
    for (var i = 0; i < placedItems.length; i++) {
        placedItems[i].embed();
    }
}

function appendToFilename(doc, extension) {
    var filePath = doc.fullName;
    var fileName = filePath.name.replace(/\.[^\.]+$/, '');
    var newFileName = fileName + ' (CHK).' + extension;
    var newPath = filePath.parent.fsName + '/' + newFileName;
    return new File(newPath);
}

function saveAsAI(doc, aiFile) {
    var aiSaveOptions = new IllustratorSaveOptions();
    aiSaveOptions.compatibility = Compatibility.ILLUSTRATOR17;
    aiSaveOptions.pdfCompatible = true;
    doc.saveAs(aiFile, aiSaveOptions);
}

function saveAsPDF(doc, pdfFile) {
    var pdfSaveOptions = new PDFSaveOptions();
    pdfSaveOptions.preserveEditability = false;
    doc.saveAs(pdfFile, pdfSaveOptions);
}

if (app.documents.length > 0) {
    var doc = app.activeDocument;

    unlockAll(doc);
    convertToCMYK(doc);
    createOutlines(doc);
    embedLinkedFiles(doc);

    var aiFile = appendToFilename(doc, 'ai');
    var pdfFile = appendToFilename(doc, 'pdf');
    saveAsAI(doc, aiFile);
    saveAsPDF(doc, pdfFile);

    alert('Script executed successfully. Saved as AI: ' + aiFile.fsName + ' and as PDF: ' + pdfFile.fsName);
} else {
    alert('No document is open.');
}

```
生成AIに聞いてみた、Pythonの変数と基本的なデータ型

https://qiita.com/Akuuuun/items/af6e00a07b9422dcd054

https://qiita.com/Akuuuun/items/f2df898769588855b405

変数と基本的なデータ型について、より詳しく説明いたします。

# 1. 変数

Pythonでは、変数は値を格納するためのコンテナのようなものです。変数名は文字またはアンダースコア(_)で始まり、文字、数字、アンダースコアを含むことができます。

```python
x = 5
name = "John"
_private = True
```

Pythonは動的型付け言語なので、変数の型を明示的に宣言する必要はありません。変数の型は、それに割り当てられた値によって自動的に決定されます。

# 2. 基本的なデータ型

Pythonには以下の基本的なデータ型があります：

## a. 数値型
   - 整数 (int)：全ての整数
   - 浮動小数点数 (float)：小数点を含む数
   - 複素数 (complex)：虚数を含む数

```python
integer = 42
float_number = 3.14
complex_number = 1 + 2j

print(type(integer))       # <class 'int'>
print(type(float_number))  # <class 'float'>
print(type(complex_number))# <class 'complex'>
```

## b. 文字列 (str)：
   文字列は、シングルクォート(' ')またはダブルクォート(" ")で囲まれたテキストです。

```python
single_quoted = 'Hello'
double_quoted = "World"
multi_line = '''This is a
multi-line string'''

print(single_quoted + " " + double_quoted)  # Hello World
print(len(multi_line))  # 文字列の長さを表示
```

## c. ブール型 (bool)：
   True または False の2つの値のみを持ちます。

```python
is_python_fun = True
is_coding_hard = False

print(is_python_fun and is_coding_hard)  # False
print(is_python_fun or is_coding_hard)   # True
print(not is_python_fun)                 # False
```

## d. None型：
   Noneは特殊な値で、「値がない」ことを表します。

```python
result = None
print(result is None)  # True
```

# 3. 型変換

Pythonでは、異なる型の間で変換を行うことができます。

```python
# 文字列から整数へ
age_str = "25"
age_int = int(age_str)
print(age_int + 5)  # 30

# 整数から浮動小数点数へ
x = 10
y = float(x)
print(y)  # 10.0

# 数値から文字列へ
num = 42
num_str = str(num)
print("The answer is " + num_str)  # The answer is 42
```

# 4. 型の確認

`type()` 関数を使用して、変数の型を確認できます。

```python
x = 5
y = "Hello"
z = 3.14

print(type(x))  # <class 'int'>
print(type(y))  # <class 'str'>
print(type(z))  # <class 'float'>
```

# 5. 変数の命名規則

- 変数名は文字またはアンダースコアで始める必要があります。
- 大文字と小文字は区別されます（age と Age は異なる変数です）。
- 予約語（if, for, whileなど）は変数名として使用できません。

```python
# 良い例
user_name = "Alice"
age_of_user = 30
_private_variable = "Secret"

# 悪い例
# 2user = "Bob"  # 数字で始まっているためエラー
# if = 10        # 予約語を使用しているためエラー
```

これらの基本的なデータ型と変数の概念を理解することは、Pythonプログラミングの基礎となります。これらを適切に使用することで、様々な種類のデータを効果的に扱い、複雑なプログラムを構築することができます。
ドメイン駆動設計入門未満

## DDDの質問

Qiita FMのnrsさん回で、雰囲気に合わないような長い質問だったのですが、
質問が読まれました！

https://open.spotify.com/show/4E7yCLeCLeQUsNqM4HXFXA

質問内容は「小規模のプロジェクトではドメイン駆動設計のメリットを感じないのですが、どのような規模でメリットが感じられるようになりますか」

質問にお答えいただいたのは次のような内容でした。

* 「ドメイン駆動設計」とはそもそも何を意味しているか？
* ソフトウェア開発全般か、レイヤードアーキテクチャか
* レイヤードアーキテクチャでは、クラスを分けることでテストが単純化される
* クラスが増えることで面倒な部分は、スケルトンを作るツールを準備する

確かに、と思いました。

質問が読まれて気が付いたのは、自分も「ソフトウェア開発全般とレイヤードアーキテクチャ」のどちらを指しているかが分からなかったところがあります。

そこまで難しくないものが階層分けなどで複雑化したわりに、その実装の方針などで議論が多数生まれ、本来のメリットであるテストの容易性よりも議論が積み重なったことにより、メリットを感じされなくなったことで、あのような質問になったように思います。

## DDDが難しかったこと

　自分にとってはDDDが難しいと感じたところは、DDDが大きな括りでの「設計」だということです。

開発で、SEとプログラマーが分かれている場合などは、「システムの設計」と「実装上の設計」も担当が分かれていて、プログラマーは後者の担当になるかと思います。
DDDでは、これらの二つの設計を包括して「設計」と呼んでいるように読めました。

ですから、例えばプログラマーに「DDDでやります」というだけで、できるものでは無いように感じました。

## 従来の開発よりも時間が必要かもしれない

　DDDで開発を行う場合、「DDDをやると決めた側」が、そのチームのメンバーに設計やアーキテクチャをうまく伝搬、伝承する必要があるように思いました。

また、モデリングなども、事前に相談する時間がなければ、プログラマーが単独でモデリングした場合など、そのモデリングが違うということで議論になるかもしれません。

また、どのようなアーキテクチャを採用していて、どういう構成が良いか、どういう方針で実装を進めるか、という、プログラマー側にお任せで行っていたことも、全体での相談が必要で、何らかの資料や詳細な説明などでカバーすることも必要になりそうです。

そして、理解する時間も必要かもしれません。アーキテクチャも人によって解釈が異なることもあります。
例えばMVCのようなフレームワークであれば置くディレクトリやクラスの命名規則がある程度決まっていてブレにくいですが、DDDはそうならないかと思います。

一方でチームを支えるリーダーのような人が優秀で、相談への対応と、どのような設計をするかという議論がうまければ、柔軟性に優れたものになりそうです。

## 戦術的DDDは重宝しそうに思いました

　DDDが難しい一方で、プログラマーが単独でも取り入れられる「戦術的DDD」は保守性という意味でも、後で議論が発生しないという意味でも良さそうに思いました。
　ユニットテストがしやすくなるのと、ロジックがドメインモデルにまとまることによって仕組みの理解がしやすくなるのはうれしいように思いました。

## まとめ

　結局のところ、分厚い本がたくさん出ているという意味でも、DDDはそこまで簡単にはならないし、DDDで開発するチーム全員が優秀な人とも限らないようにも思います。

　一方で世の中のニーズもビジネスも高度化、複雑化しているので、サービスの保守にはDDDのような手法や技術が欠かせないようにも思いました。

 そのような意味ではDDDを分かりやすく伝えてくださる先人の方々には感謝が絶えません。

 （まとめ方がわからなくなったのでここで終わります）
Astro で Google Fonts の日本語フォントの読み込みを高速化できる（場合がある）（かもしれない）

## この記事の概要

Astro を使って遊んでいたら、たまたま Web フォントの読み込みを高速化できそうな気配を感じました。

ただ、細かいことは検証できていない[^1]ので、あくまで「条件があえばこういうのもできるのかもしれない」くらいで捉えていただければ幸いです。

[^1]: 絵文字やサロゲートペア、文字の種類が増えすぎた場合どうなるか、など。

## 概要

1. `getCollection`を使い、`props`の`body`を取得する
1. Google Fonts の URL パラメーターに`text={body}`を指定する

## 詳細

コンテンツコレクションを利用し、動的なルーティングをしているとします。

フロントマター内に Markdown をプレーンでユニークな文字列に変換する関数を作り、`body`を渡します。

そしてフォントの`link`タグの URL パラメーターに先ほど作った文字列を渡します。

かなり省略していますが、重要な部分でいえばこのようなコードになります。

```jsx:src/pages/posts/[...slug].astro
---
import { getCollection } from 'astro:content';

export async function getStaticPaths() {
  const blogEntries = await getCollection("blog");
  return blogEntries.map(entry => ({
    params: { slug: entry.slug }, props: { entry },
  }));
}

const { entry } = Astro.props;
const { Content } = await article.render();

function extractUniqueText(body: string) {
  // Markdown 本文のうち、改行や箇条書きなどをなくす処理
  // 文字列をユニークにする処理
  
  return uniqueText;
}

const entryBody = extractUniqueText(entry.body);
---

<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
    <meta name="viewport" content="width=device-width" />
    {/* などなど */}
    <link rel="preconnect" href="https://fonts.googleapis.com" />
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
    <link
      href={`https://fonts.googleapis.com/css2?family=Noto+Serif+JP:wght@200..900&display=swap&text=${entryBodyBody}`}
      rel="stylesheet"
    />
  </head>
  <body>
    <Content />
  </body>
</html>
```

Google Fonts のリクエスト最適化については公式ドキュメントにも載っています。

https://developers.google.com/fonts/docs/getting_started?hl=ja#optimizing_your_font_requests

## 結果

今回は Noto Serif JP を指定していたのですが、ちゃんと適用されています。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/500d2e9b-1c63-6cbe-f669-877c06dbf067.png)

`text=`なしの際、Chrome のネットワークタブから見るとこのようになっています。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/1ce384b3-dc7b-0a10-49af-22bc525c8395.png)

いつもの Google Fonts の挙動です。

一方で今回の場合はこのようになりました。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/f6d599c4-eb2d-9eb7-0060-e545a2974008.png)

1 つのフォントファイルになっている分、単体でのファイルサイズは大きくなっているのですが、合計した容量や時間は効率良くなっています。

果たしてこれが、何種類程度までなら高速なのかとか、どの日本語フォントでもこうなるのかとか、細かなことは検証できていません。

しかし上手くやれば、パフォーマンスをあまり落とさず、日本語 Web フォントを使えるのではないかという雰囲気を感じています。

## リアルに使うなら？

とは言え本文すべてを渡すと、どこかでパフォーマンス悪化を招きそうな気もします。

現実的な使い方を考えるなら`const { headings } = await article.render();`で見出しを取得し、見出しにだけは Web フォントを使う、などでしょうか。

あるいは、`blog.data.title`などで記事のタイトルだけを取得し、そこに使うとか。

いずれにせよ、Astro の機能で記事中の特定の情報だけを引っ張ってきやすいので、上手く組み合わせて使うと良いような気がしています。
生成AIに聞いてみた、Pythonのより高度なトピック

https://qiita.com/Akuuuun/items/af6e00a07b9422dcd054

# 8. より高度なトピック
   - ジェネレータと反復子
   - デコレータ
   - コンテキストマネージャ

より高度なトピックについて、サンプルコードを交えて詳しく説明いたします。ジェネレータと反復子、デコレータ、コンテキストマネージャの3つのトピックについて順番に解説していきます。

## 1. ジェネレータと反復子

ジェネレータは、イテレーション（繰り返し処理）を行うための特殊な関数です。通常の関数と異なり、`yield` キーワードを使用して値を生成し、状態を保持しながら実行を一時停止できます。

サンプルコード：

```python
def fibonacci_generator(n):
    a, b = 0, 1
    for _ in range(n):
        yield a
        a, b = b, a + b

# ジェネレータの使用
fib = fibonacci_generator(10)
for num in fib:
    print(num)

# リスト内包表記でジェネレータ式を使用
even_squares = (x**2 for x in range(10) if x % 2 == 0)
print(list(even_squares))
```

このコードでは、フィボナッチ数列を生成するジェネレータと、偶数の二乗を生成するジェネレータ式を示しています。ジェネレータを使用すると、大量のデータを扱う際にメモリ効率が向上します。

## 2. デコレータ

デコレータは、既存の関数やクラスの動作を変更したり拡張したりするための強力な機能です。関数やクラスの定義の前に`@`記号を付けて使用します。

サンプルコード：

```python
import time

def timing_decorator(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f"{func.__name__} の実行時間: {end_time - start_time:.4f} 秒")
        return result
    return wrapper

@timing_decorator
def slow_function():
    time.sleep(2)
    print("処理が完了しました")

slow_function()

# クラスデコレータの例
def singleton(cls):
    instances = {}
    def get_instance(*args, **kwargs):
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
        return instances[cls]
    return get_instance

@singleton
class DatabaseConnection:
    def __init__(self):
        print("新しいデータベース接続を作成しました")

# インスタンスの作成
conn1 = DatabaseConnection()
conn2 = DatabaseConnection()
print(conn1 is conn2)  # True
```

このコードでは、関数の実行時間を測定するデコレータと、クラスをシングルトンパターンに変換するデコレータを示しています。デコレータを使用すると、コードの再利用性と可読性が向上します。

## 3. コンテキストマネージャ

コンテキストマネージャは、リソースの獲得と解放を自動的に行うための仕組みです。`with`文と組み合わせて使用され、ファイルの操作やデータベース接続など、リソースの管理に役立ちます。

サンプルコード：

```python
class Timer:
    def __enter__(self):
        self.start = time.time()
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.end = time.time()
        print(f"処理時間: {self.end - self.start:.4f} 秒")

# コンテキストマネージャの使用
with Timer():
    time.sleep(1.5)
    print("処理が完了しました")

# ファイル操作の例
with open('example.txt', 'w') as f:
    f.write('Hello, World!')

# contextlibを使用したコンテキストマネージャ
from contextlib import contextmanager

@contextmanager
def tempdirectory():
    import tempfile
    import shutil
    import os
    
    temp_dir = tempfile.mkdtemp()
    try:
        yield temp_dir
    finally:
        shutil.rmtree(temp_dir)

# 一時ディレクトリの使用
with tempdirectory() as temp_dir:
    print(f"一時ディレクトリ: {temp_dir}")
    # ここで一時ディレクトリを使用する処理を行う
```

このコードでは、処理時間を計測するカスタムコンテキストマネージャ、ファイル操作の例、および`contextlib`モジュールを使用した一時ディレクトリを作成するコンテキストマネージャを示しています。コンテキストマネージャを使用すると、リソース管理が簡単になり、コードの安全性が向上します。

これらの高度なトピックを理解し、適切に使用することで、より効率的で保守性の高いPythonコードを書くことができます。これらの概念は、大規模なプロジェクトや複雑なシステムの開発において特に重要です。
生成AIに聞いてみた、Pythonのモジュールとライブラリ

https://qiita.com/Akuuuun/items/af6e00a07b9422dcd054

# 5. モジュールとライブラリ
   - モジュールの使用方法
   - 標準ライブラリ
   - 外部ライブラリ
   - モジュールとライブラリの利点

モジュールとライブラリは、Pythonプログラミングにおいて非常に重要な概念です。これらを使用することで、コードの再利用性が高まり、複雑な機能を簡単に実装できるようになります。詳しく説明し、サンプルコードを交えて解説していきます。

## 1. モジュールとは

モジュールは、Python のコードを論理的に組織化し、関連する機能をグループ化するための方法です。モジュールは単にPythonファイル(.py)であり、変数、関数、クラスなどを含むことができます。

例えば、math_operations.py という名前のファイルを作成し、以下のような内容を記述したとします：

```python
def add(a, b):
    return a + b

def subtract(a, b):
    return a - b

PI = 3.14159
```

これで、math_operations というモジュールが作成されました。

## 2. モジュールの使用方法

作成したモジュールは、他のPythonスクリプトからインポートして使用することができます。

```python
import math_operations

result = math_operations.add(5, 3)
print(result)              # 8

print(math_operations.PI)  # 3.14159
```

また、特定の関数や変数のみをインポートすることもできます：

```python
from math_operations import add, PI

result = add(5, 3)
print(result)  # 8

print(PI)      # 3.14159
```

## 3. 標準ライブラリ

Pythonには、多くの有用な機能が組み込まれた標準ライブラリが付属しています。これらは追加のインストールなしで使用できます。

例えば、randomモジュールを使用して乱数を生成する例を見てみましょう：

```python
import random

# 0から9までのランダムな整数を生成
random_number = random.randint(0, 9)
print(random_number)

# リストからランダムな要素を選択
fruits = ["apple", "banana", "orange", "grape"]
random_fruit = random.choice(fruits)
print(random_fruit)
```

また、datetimeモジュールを使用して日付と時刻を扱う例：

```python
from datetime import datetime, timedelta

# 現在の日時を取得
now = datetime.now()
print(f"Current date and time: {now}")
# Current date and time: 2024-07-04 22:03:12.402514

# 1週間後の日付を計算
one_week_later = now + timedelta(weeks=1)
print(f"Date after one week: {one_week_later}")
# Date after one week: 2024-07-11 22:03:12.402514
```

## 4. 外部ライブラリ

Python エコシステムには、PyPI (Python Package Index) を通じて利用可能な多くの外部ライブラリがあります。これらは pip というパッケージマネージャーを使用してインストールできます。

例えば、データ分析によく使われる pandas ライブラリをインストールして使用する例を見てみましょう：

まず、コマンドラインで以下のコマンドを実行してpandasをインストールします：

```
pip install pandas
```

そして、以下のようにpandasを使用できます：

```python
import pandas as pd

# サンプルデータの作成
data = {
    'Name': ['Alice', 'Bob', 'Charlie'],
    'Age': [25, 30, 35],
    'City': ['New York', 'San Francisco', 'Los Angeles']
}

# データフレームの作成
df = pd.DataFrame(data)

print(df)
#       Name  Age           City
# 0    Alice   25       New York
# 1      Bob   30  San Francisco
# 2  Charlie   35    Los Angeles

print("\nAverage age:", df['Age'].mean())
# Average age: 30.0
```

このスクリプトは、簡単なデータフレームを作成し、基本的な統計情報を計算します。

## 5. モジュールとライブラリの利点

- コードの再利用性: 一度作成したコードを他のプロジェクトで再利用できます。
- コードの組織化: 関連する機能をグループ化し、コードを整理できます。
- 機能の拡張: 標準ライブラリや外部ライブラリを使用することで、複雑な機能を簡単に実装できます。
- 開発時間の短縮: すでに実装された機能を利用することで、開発時間を大幅に短縮できます。

モジュールとライブラリの使用は、効率的で保守性の高いPythonプログラムを書くための重要なスキルです。標準ライブラリを深く理解し、プロジェクトのニーズに応じて適切な外部ライブラリを選択・使用する能力を身につけることで、Pythonプログラマーとしての能力が大きく向上します。
生成AIに聞いてみた、Pythonのエラー処理

https://qiita.com/Akuuuun/items/af6e00a07b9422dcd054

# 4. エラー処理
   - try-except文の使用
   - 複数の例外の処理
   - `else`と`finally`の使用
   - 例外の再発生
   - カスタム例外の作成

エラー処理はプログラミングにおいて非常に重要な概念です。Pythonでは、`try-except`文を使用してエラー処理を行います。これにより、プログラムが予期せぬエラーに遭遇した際に、適切に対応することができます。

以下、Pythonのエラー処理について詳しく説明し、サンプルコードを交えて解説します。

## 1. 基本的な`try-except`文の使用

最も基本的なエラー処理は、`try-except`文を使用することです。

```python
try:
    # エラーが発生する可能性のあるコード
    result = 10 / 0
except ZeroDivisionError:
    # エラーが発生した場合の処理
    print("0で割ることはできません")
```

この例では、0で割ろうとしているため`ZeroDivisionError`が発生します。`except`ブロックでこのエラーをキャッチし、適切なメッセージを表示しています。

## 2. 複数の例外の処理

複数の種類の例外を個別に処理することもできます。

```python
try:
    num = int(input("数字を入力してください: "))
    result = 10 / num
except ValueError:
    print("有効な数字を入力してください")
except ZeroDivisionError:
    print("0で割ることはできません")
```

この例では、ユーザーの入力が数字でない場合は`ValueError`が、0の場合は`ZeroDivisionError`が発生します。それぞれに対して適切な処理を行っています。

## 3. `else`と`finally`の使用

`try-except`文には`else`と`finally`ブロックを追加することができます。

```python
try:
    file = open("example.txt", "r")
    content = file.read()
except FileNotFoundError:
    print("ファイルが見つかりません")
else:
    print("ファイルの内容:", content)
finally:
    file.close()
```

`else`ブロックは例外が発生しなかった場合に実行されます。`finally`ブロックは例外の発生有無に関わらず常に実行されます。この例では、ファイルを開く操作が成功した場合にのみ内容を表示し、成功・失敗に関わらずファイルを閉じています。

## 4. 例外の再発生

場合によっては、例外をキャッチした後に再度発生させたいことがあります。

```python
def process_data(data):
    try:
        result = data['key'] / 0
    except KeyError:
        print("必要なキーが見つかりません")
        raise  # KeyErrorを再発生させる
    except ZeroDivisionError:
        print("0での除算が行われました")
        raise ValueError("無効な操作です")  # 新しい例外を発生させる

try:
    process_data({'key': 0})
except ValueError as e:
    print("エラーが発生しました:", str(e))
```

この例では、`process_data`関数内で`KeyError`をキャッチした場合はそのまま再発生させ、`ZeroDivisionError`の場合は新たに`ValueError`を発生させています。

## 5. カスタム例外の作成

独自の例外クラスを作成することで、より具体的なエラー処理が可能になります。

```python
class InvalidAgeError(Exception):
    pass

def verify_age(age):
    if age < 0:
        raise InvalidAgeError("年齢は0以上である必要があります")
    elif age > 120:
        raise InvalidAgeError("年齢が現実的ではありません")
    else:
        print("有効な年齢です")

try:
    verify_age(150)
except InvalidAgeError as e:
    print("エラー:", str(e))
```

この例では、`InvalidAgeError`という独自の例外クラスを定義し、年齢の検証に使用しています。

エラー処理を適切に行うことで、プログラムの堅牢性が向上し、予期せぬ状況でも適切に対応できるようになります。ただし、過剰なエラー処理はコードの可読性を下げる可能性があるため、バランスを取ることが重要です。

これらの例を参考に、実際のプロジェクトでエラー処理を実装してみてください。様々な状況でエラー処理を行うことで、より信頼性の高いプログラムを作成することができます。
生成AIに聞いてみた、Pythonの入出力

https://qiita.com/Akuuuun/items/af6e00a07b9422dcd054

# 3. 入出力
   - コンソールからの入力と出力
   - ファイルの読み書き

pythonの入出力について、詳しく説明し、サンプルコードを交えてお教えします。入出力は大きく分けて、コンソールからの入出力とファイルの入出力があります。それぞれについて説明していきます。

## 1. コンソールからの入出力

コンソールからの入力には`input()`関数を、出力には`print()`関数を使用します。

### a) 入力 (`input()`)

`input()`関数は、ユーザーからの入力を文字列として受け取ります。

```python
name = input("あなたの名前を入力してください: ")
print(f"こんにちは、{name}さん!")
# あなたの名前を入力してください:  〇〇
# こんにちは、〇〇さん!

age = int(input("あなたの年齢を入力してください: "))
print(f"あなたは{age}歳ですね。")

# あなたの年齢を入力してください:  △△
# あなたは△△歳ですね。
```

**注意点：**
- `input()`は常に文字列を返すので、数値として扱いたい場合は、`int()`や`float()`でキャストする必要があります。

### b) 出力 (`print()`)

`print()`関数は、コンソールに出力を表示します。

```python
print("Hello, World!")  # 単純な文字列の出力
# Hello, World!

x = 10
y = 20
print(f"xの値は{x}、yの値は{y}です。")  # f-stringを使用した出力
# xの値は10、yの値は20です。

print("x =", x, "y =", y)  # 複数の値をカンマで区切って出力
# x = 10 y = 20
```

**`print()`関数の追加機能：**
- `sep`パラメータ：出力する項目の間の区切り文字を指定
- `end`パラメータ：出力の最後に追加する文字を指定

```python
print("Hello", "World", sep="-", end="!\n")  # Hello-World!
```

## 2. ファイルの入出力

ファイルの操作には、主に以下の手順があります：
1. ファイルを開く (`open()`)
2. ファイルから読み込む、またはファイルに書き込む
3. ファイルを閉じる (`close()`)

### a) ファイルの読み込み

```python
# ファイルを読み込みモードで開く
with open('sample.txt', 'r', encoding='utf-8') as file:
    # ファイルの内容を全て読み込む
    content = file.read()
    print(content)
    
    # ファイルを先頭に戻す
    file.seek(0)
    
    # 1行ずつ読み込む
    for line in file:
        print(line.strip())  # 改行を取り除いて表示
```

### b) ファイルへの書き込み

```python
# ファイルを書き込みモードで開く（既存の内容は上書きされる）
with open('output.txt', 'w', encoding='utf-8') as file:
    file.write("Hello, World!\n")
    file.write("This is a new line.")

# ファイルを追記モードで開く（既存の内容の後ろに追加される）
with open('output.txt', 'a', encoding='utf-8') as file:
    file.write("\nThis line is appended.")
```

### c) CSVファイルの操作

CSVファイルの読み書きには、`csv`モジュールを使用すると便利です。

```python
import csv

# CSVファイルの書き込み
data = [
    ['Name', 'Age', 'City'],
    ['Alice', '30', 'New York'],
    ['Bob', '25', 'Los Angeles']
]

with open('data.csv', 'w', newline='', encoding='utf-8') as file:
    writer = csv.writer(file)
    writer.writerows(data)

# CSVファイルの読み込み
with open('data.csv', 'r', encoding='utf-8') as file:
    reader = csv.reader(file)
    for row in reader:
        print(', '.join(row))
```

### d) JSONファイルの操作

JSONファイルの読み書きには、`json`モジュールを使用します。

```python
import json

# JSONファイルの書き込み
data = {
    "name": "John Doe",
    "age": 30,
    "city": "New York"
}

with open('data.json', 'w', encoding='utf-8') as file:
    json.dump(data, file, indent=4)

# JSONファイルの読み込み
with open('data.json', 'r', encoding='utf-8') as file:
    loaded_data = json.load(file)
    print(loaded_data)
```

以上が、Pythonにおける基本的な入出力の操作です。これらの方法を使って、ユーザーとのインタラクションやファイルの操作を行うことができます。実際のプログラムでは、これらの基本的な操作を組み合わせて、より複雑なタスクを実行することになります。

***入出力操作を行う際は、以下の点に注意してください：***

1. ファイル操作後は必ず`close()`するか、`with`文を使用してファイルを自動的に閉じるようにしましょう。
2. 適切なエンコーディングを指定して、文字化けを防ぎましょう。
3. ファイル操作時は、ファイルが存在しない場合や権限がない場合などのエラーハンドリングを適切に行いましょう。

これらの基本を押さえた上で、実際のプロジェクトや課題に取り組むことで、より実践的なスキルを身につけることができます。
コーディングテストが全然解けなかったのでpaizaを解き始めた

# 初めに
初めまして！私は現在修士一年の学生でエンジニアを目指して就活しています。
具体的には、気になる企業のインターンへ参加したり、興味がなくともコーディングテストを受けてみて日常的な学習に活用しています。

# コーディングテスト対策をしようと思った動機
私はこれまで大学の課題や趣味でコーディングを経験してきたので、それなりにコーディングをできる自負がありました。しかし、いざatcoderのABCに参加してみると、A〜B問題くらいしか解けないと言う事実に直面し、正直凹みました。加えて、6月上旬に参加したインターンで知り合った人たちが、atcoderでC〜Dくらいは平均して解けるレベルということを知り、危機感を持ちました。

あと、ビズリーチのインターンのコーディング試験が解けなすぎて悔しかったです笑

# 近況
とりあえず、paizaでコーディングテストの対策を始めました！
一昨日初めて、Cランクの問題の一番簡単な問題（C084:枠で囲む）を解いてすんなりとCランクに到達しました。調子に乗って、Bランクに挑戦しましたが解けませんでした、、、

今後は、Bランクの問題を解くノウハウを吸収するべく以下のことに取り組んでいきます。
* 毎日Cランク問題を一問解く(なるべくBランクの問題のレート1500に近いものに挑戦する)
* Bランク獲得ストーリー（講座）を進める

Cランク問題は、初めに解いた簡単なものと比較すると全然難しかったので私の現在のレベルの少し上くらいで良いなと思いました。また、Bランクの講座は、そもそもの書き方の部分で必要なアルゴリズムとデータ構造の知識を着実に入れて、コーディングできるようにするという目的です。

# 目標
せっかくコーディング力を鍛えるなら、ゴールを設定して達成したいと思っています！なので、私がコーディング力を身につけて叶えたい夢を下に書きます！（随時更新します）
* Bランクに到達して長期インターンのバイトを始める（今のバイトを辞めたい）
* 本採用でメガベンチャーのコーディングテストを突破する

# あとがき
以上の目標達成に向けて頑張ります！
就活生の方、ライバルでもあり仲間だと思うので共に頑張りましょう！
技術面で勉強した内容を随時、記事としてまとめていきます！
是非、フォローお願いします！！
生成AIに聞いてみた、Pythonのデータ構造

https://qiita.com/Akuuuun/items/af6e00a07b9422dcd054

# 2. データ構造
   - リスト、タプル、辞書、セット
   - これらのデータ構造の操作方法

データ構造は、プログラミングにおいて非常に重要な概念です。Pythonには、主に以下の4つの基本的なデータ構造があります：リスト、タプル、辞書、セット。それぞれについて詳しく説明し、サンプルコードを交えて解説します。

## 1. リスト (List)

リストは、順序付けられた変更可能なデータ構造です。角括弧 `[]` で囲んで定義します。

```python
# リストの作成
fruits = ['apple', 'banana', 'orange']

# 要素へのアクセス
print(fruits[0])  # apple

# 要素の追加
fruits.append('grape')
print(fruits)     # ['apple', 'banana', 'orange', 'grape']

# 要素の削除
removed_fruit = fruits.pop()
print(removed_fruit)  # grape
print(fruits)         # ['apple', 'banana', 'orange']

# リストのスライス
print(fruits[1:3])    # ['banana', 'orange']

# リストの長さ
print(len(fruits))    # 3
```

## 2. タプル (Tuple)

タプルは、順序付けられた変更不可能なデータ構造です。丸括弧 `()` で囲んで定義します。

```python
# タプルの作成
coordinates = (10, 20)

# 要素へのアクセス
print(coordinates[0])  # 10

# タプルの分割
x, y = coordinates
print(x, y)            # 10 20

# タプルの結合
new_coordinates = coordinates + (30,)
print(new_coordinates)   # (10, 20, 30)

# タプルの要素数
print(len(coordinates))  # 2
```

## 3. 辞書 (Dictionary)

辞書は、キーと値のペアを持つ変更可能なデータ構造です。波括弧 `{}` で囲んで定義します。

```python
# 辞書の作成
person = {'name': 'Alice', 'age': 30, 'city': 'New York'}

# 値へのアクセス
print(person['name'])  # Alice

# 新しいキーと値の追加
person['job'] = 'Engineer'
print(person)  # {'name': 'Alice', 'age': 30, 'city': 'New York', 'job': 'Engineer'}

# キーの存在確認
print('age' in person)  # True

# キーと値の取得
for key, value in person.items():
    print(f"{key}: {value}")

# キーの削除
del person['city']
print(person)  # {'name': 'Alice', 'age': 30, 'job': 'Engineer'}
```

## 4. セット (Set)

セットは、重複のない要素の集合を表す変更可能なデータ構造です。波括弧 `{}` または `set()` 関数を使って定義します。

```python
# セットの作成
fruits = {'apple', 'banana', 'orange'}

# 要素の追加
fruits.add('grape')
print(fruits)  # {'orange', 'banana', 'apple', 'grape'}

# 要素の削除
fruits.remove('banana')
print(fruits)  # {'orange', 'apple', 'grape'}

# セット演算
set1 = {1, 2, 3, 4, 5}
set2 = {4, 5, 6, 7, 8}

# 和集合
print(set1 | set2)  # {1, 2, 3, 4, 5, 6, 7, 8}

# 積集合
print(set1 & set2)  # {4, 5}

# 差集合
print(set1 - set2)  # {1, 2, 3}
```

## 5. これらのデータ構造の操作方法

**これらのデータ構造は、それぞれ異なる特性と使用場面があります：**

- リストは順序付けられた要素の集合を扱う際に便利です。
- タプルは変更不可能なデータを扱う際や、関数の複数の戻り値として使用されます。
- 辞書はキーと値のペアを扱う際に便利で、高速なデータ検索が可能です。
- セットは重複のないユニークな要素の集合を扱う際や、集合演算を行う際に便利です。

これらのデータ構造を適切に選択し、組み合わせることで、効率的なプログラムを書くことができます。各データ構造の特性を理解し、状況に応じて最適なものを選ぶことが重要です。
セルの内容を配列に挿入

個人メモ

```:VBA
Sub test()
    Dim i As Long
    Dim v_in As Variant, v_out As Variant
    
    v_in = Range("A1:A5")
    v_out = Range("C1:C5")
    
    
    For i = 1 To 5
       v_out(i, 1) = Split(v_in(i, 1), ",")
    Next
    
    For i = 1 To 5
        If v_out(i, 1)(1) = "AAA" Then
            Cells(i, 3).Value = v_out(i, 1)(1)
        End If
    Next
End Sub
```
セルの内容を配列に挿入。
【Expo + React Native】Splash画面起動後、iOSアプリがクラッシュする事象を解決した

Expo + React Native で iOSアプリを開発中に直面した問題を解決したため、その方法を記録しておきます。


## 事象
- `npx expo start`や`eas update`にて発行されたQRコード経由でExpo Go にてアプリ起動させると正常に動く（Splash画面起動 → アプリのトップページ起動）
- `eas build -p ios`でiOS用ビルド＆App Store Connect へ ipaファイルアップロードし、iPhone実機で Testflight からダウンロードしたアプリ起動させるとSplash画面起動後、アプリがクラッシュする


## 結論
**使用していたページ遷移用ライブラリの必須ライブラリである `react-native-gesture-handler` のインストール＆設定が足りていなかった。**

アプリクラッシュに関する情報検索やコンポーネントの書き方変更など色々試しましたが、結果的にかなり初歩的なミスでした…。

ページ遷移のために導入したライブラリは、以下の2つ。
- `@react-navigation/native` ([公式ドキュメント](https://reactnavigation.org/docs/getting-started/#installation)) 
- `@react-navigation/stack` ([公式ドキュメント](https://reactnavigation.org/docs/stack-navigator/#installation))

それぞれの公式ドキュメントを確認すると、正しいインストール方法が明記されていました。

```ruby:react-navigation/native
# 1. ライブラリ本体インストール
npm install @react-navigation/native

# 2. 必須ライブラリインストール
# Expoプロジェクトの人はこっち
npx expo install react-native-screens react-native-safe-area-context
# 素のReact Nativeプロジェクトの人はこっち
npm install react-native-screens react-native-safe-area-context

```

```ruby:react-navigation/stack
# 1. ライブラリ本体インストール
npm install @react-navigation/stack

# 2. 必須ライブラリインストール
# Expoプロジェクトの人はこっち
npx expo install react-native-gesture-handler
# 素のReact Nativeプロジェクトの人はこっち
npm install react-native-gesture-handler

# 3. エントリーファイル（index.jsやApp.js等）の一行目（上に何も文がないことを確認）に以下を追記
import 'react-native-gesture-handler';
```

特に`react-navigation/stack`の手順3に関しては、以下のような警告も記載されてました。

:::note warn
警告
AndroidまたはiOS向けにビルドしている場合、このステップをスキップしないでください。開発時には問題なく動作していても、本番でアプリがクラッシュする可能性があります。他のプラットフォームには適用できません。
:::

手順通りに足りない必須ライブラリをインストール＆設定を行い、実機で無事にアプリ起動 :confetti_ball:

## おわりに
解決にかなり時間をかけてしまいましたが、アプリが実機で無事に動くようになってよかったです。
ライブラリ導入時や困った時は、改めてドキュメントを読む！という学びになりました。