OmniAICreator/Qiita-1.07M huggingface dataset:
SAA 学習メモ 機械学習サービス 関連

## Amazon Comprehend
機械学習を利用した自然言語処理サービスで、テキストデータ解析のための様々な機能を提供する
※ Comprehend = 理解する

- エンティティ認識
  - テキスト内の登場人物を識別する
- 感情分析
  - ポジティブ・ネガティブといった感情を分析
- キーフレーズ抽出
  - 特定のキーワードに関連する情報を抽出
- Comprehend Medical
  - 医療情報に特化したサービス
  - 電子健康記録、臨床試験レポート、医療ノートなどから情報を抽出できる

## Amazon Transcribe
機械学習を利用した音声認識サービスで、音声 ⇒ テキスト の変換を行う
※ Transcribe = 書き写す

- リアルタイム文字お越し
- 通話記録データのテキスト化
- 動画の字幕付け

## Amazon Textract
機械学習を利用したOCR（Optical Character Recognition: 工学的文字認識）サービス
※ Textract = text + extract(抽出)

- スキャンしたドキュメントやPDFからテキストやデータを抽出
- 手書きのテキストや表形式のデータも読み取り可能

## Amazon Translate
機械学習を利用したテキストの翻訳機能を提供するサービス

- 大量のドキュメントデータを一度に翻訳
- Webコンテンツやアプリケーションの複数言語への対応

## Amazon Forecast
機械学習を利用した時系列予測を提供するフルマネージドサービス

- 季節ごとの商品需要予測
- プロモーション効果の予測
- 予算計画
- スタ風の要員計画 など
[VSCode] Github Copilot Chatが「Cannot read properties of undefined (reading 'map')」のエラーになる

# エラー

突然、何をやっても以下のエラーになってしまった
![スクリーンショット 2025-02-11 21.38.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900714/ce471869-1f99-93ff-5c93-12e18922f92e.png)

症状としては、コード補完は正常に動くが、chatの方だけこのエラーが発生している

# Github Copilot Chatのバージョンを下げて解決

おそらく自動で最新バージョンに上がったことがきっかけでこのエラーが発生したと思われる。なので以前のバージョンに戻してみたところ解決した。

VSCodeの拡張機能サイドメニュー > Github Copilot Chat > 右クリック > 特定のバージョンをインストール を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900714/28f5e28b-df6c-6270-eb7f-8cafb84eec01.png)

最新ではないバージョンを指定する（最新の1つ前の `0.23.2` に下げた）![スクリーンショット 2025-02-11 21.46.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900714/88e22d46-e50c-7d72-7e22-ba19a5c6f29b.png)

バージョンを変更すると、拡張機能の再起動が求められるので再起動すると直った


# 試したけど解決しなかったこと

- VSCodeの再起動
- 拡張機能の再起動
SAA 学習メモ Storage Gateway 関連

## Storage Gataway
- オンプレミスからAWSのストレージサービスへのアクセスを高速かつセキュアに行うことができるサービス
- ユースケース
  - S3を共有ストレージとして利用
  - 災害対策を目的としたバックアップやアーカイブ
  - アクセス頻度の低いデータを自社サーバーからAWSへ移動するなど
- ストレージサービスではなく、オンプレとAWSストレージサービスとの橋渡しをするサービス
- 使用するプロトコルが異なる複数のゲートウェイタイプが用意されている

### ファイルゲートウェイ
- オンプレミスからNFS、SMBを使用してAWSストレージにアクセスできるサービス
- ローカル（オンプレ）にキャッシュストレージを持つため低レイテンシでのアクセスも可能
#### 対応するストレージサービス
- S3
  - ストレージ形式：ファイル単位
  - 概要
    - NFS、SMBに対応しており、S3をファイル共有ストレージとして使用できる
- FSx
  - ストレージ形式：ファイル単位
  - 概要
    - SMBに対応しており、FSx for Windows をファイル共有ストレージとして使用できる
### ボリュームゲートウェイ
- オンプレからiSCSI(Internet Small Computer System Interface)を使用して、S3をブロックストレージボリュームとして利用できるサービス
- サーバーはiSCSIで接続されたストレージをローカルディスクとして利用できる
- ボリュームストレージを上のデータはS3にEBSスナップショットとして保存可能で、災害対策やバックアップに利用できる
※ iSCSI = コンピュータのストレージを接続するSCSIをTCP/IPで実現したプロトコル
#### ボリュームゲートウェイの種類
- キャッシュ型（キャッシュボリューム）
  - ストレージ形式：ボリューム単位
  - 概要
    - すべてのデータをS3上に保存しつつ、高頻度のアクセスデータのみをオンプレのキャッシュストレージにコピーする
    - データがキャッシュ上に存在しない場合はS3へアクセスするので遅延が発生するが、オンプレのストレージ容量を抑えることができる
- 保管型（ストアドボリューム）
  - ストレージ形式：ボリューム単位
  - 概要
    - すべてのデータをオンプレのボリュームストレージに保存しつつ、S3上へデータのスナップショットを非同期で保存する
    - キャッシュ型とは異なり全データのアクセス先がオンプレになるので、S3へのアクセス遅延が発生しない
### テープゲートウェイ
- ストレージ形式：仮想テープ単位
- 概要
  - 物理テープストレージの代替として使用できる
SAA 学習メモ Snow Family 関連

## Snow Family
- オンプレの大量のデータを専用の物理デバイスを利用して安全に転送するためのサービス
- AWSからデバイスが貸し出され、ユーザーが移行対象データをデバイスへ取り込む
- デバイスをAWSに返送するとデータがS3に保存される
- データ量に応じて複数のデバイスを利用することも可能
- 必要に応じて、CPUやメモリを搭載したストレージも選択でき、IoT端末やエッジコンピューティングにも利用可能
- コンピューティング用途の場合は複数台で構成するクラスターの注文も可能で、耐久性・耐障害性を向上できる
- デバイスはインターネット不要のオフライン環境で動作する
- オプションとして、AMIやLambda関数を設定可能で、データ転送時に自動で特殊な処理やデータ分析を実行できる

## Snow Family の種類
### Snowcoen
- データ転送・保存やエッジコンピューティングに対応したサービス
- デバイスがコンパクトなため、IoTや持ち運び用途にも利用可能
- 物理的な輸送ではデバイスからS3への移行に限られる
- DataSyncを使用してオンラインでデータを転送することも可能
- DataSyncエージェントがプリインストールされている
- DataSyncを使用した場合の転送先はFSx for Windows で、アクセス権限を保持したまま移行可能
- ストレージ容量
  - HDD: 8TB
  - SSD: 14TB
### Snowball
- Snowball Edge Storage Optimized
  - 転送用ストレージとしての利用が主
  - 大規模なデータ転送に適している
  - オンプレからS3へのインポートだけでなく、S3からのエクスポートにも対応
  - インポート時はからのデバイスが送付される
  - エクスポート時は指定したS3バケットからデータがロードされた状態でデバイスが届く
  - ストレージ容量
    - HDD: 80TB
    - SSD: 210TB
- Snowball Edge Compute Optimized
  - vCPUやメモリが搭載されており、エッジコンピューティングが可能
  - オフライン環境でも高度な情報処理が必要なケースに適している
  - ストレージ容量
    - HDD: 39.5TB
    - SSD: 28TB

## 容量での比較
Snowball Storage Optimized > Snowball Compute Optimized > Snowcone
- 小容量ならSnowcone

## クラウドへのデータ移行方法比較
データ移行支援サービスとしては以下がある
- AWS Storage Gataway
- AWS Data Sync

上記サービスとSnow Familyとの大きな違いは、オフラインでデータ移行可能かどうか。
上記サービスはオンラインでデータ移行するため、リアルタイムでデータが更新される場合やシステムを停止できないケースでの移行に向いている。
Snow Familyはオフラインでのデータ移行サービスのため、バックアップデータやログファイルなどの静的データの一括以降に適している。
SAA 学習メモ EC2 関連

## インスタンスクラス
### M = 汎用
- 特定のリソースに負荷が偏っていない、多くの環境に適している
### T = 汎用(CPUバースト)
- CPU処理のバーストが可能
- アイドル時間の長い焼酎規模のデータベースサーバーや解発環境に適している
### C = コンピューティング最適化
- 高性能なCPUを手今日するファミリー
- 負荷の高いバッチ処理サーバーやアクセス頻度の高いWebサーバーに適している
### R, X = メモリ最適化
- 大容量のメモリを提供するファミリー
- リアルタイムでのビックデータ解析を処理するサーバーやアクセス頻度の高いデータベースサーバーなどに適している
### P, G, F = 最速コンピューティング
- 機械学習推論や3Dグラフィックスを大量に処理するサーバー安堵に適している
### I, D, H = ストレージ最適化
- 高性能なローカルストレージを提供するファミリー
- 高いディスクスループットや大容量のローカルストレージが求められる環境に適している

## プレイスメントグループ
### パーティションプレイスメントグループ
- パーティションはラックごとの論理グループ
- 各パーティションはラックを共有しないためハードウェア障害の影響を軽減する
### クラスタープレイスメントグループ
- グループ内のインスタンスを単一AZの物理的に近い距離に配置するためインスタンス同士の通信に遅延が発生しにくい
- 単一AZにしか配置できないため、可用性を犠牲にしてでもインスタンス間の通信遅延をなくしたい時に使用
### スプレッドプレイスメントグループ
- インスタンスは異なるラックに配置され、ラック内には１つのインスタンスしか配置されない
- インスタンスがハードウェアを共有しないので、ハードウェア障害の影響を軽減できる
- 異なるAZにインスタンスを配置可能

## インスタンスストア
- 一部のEC2インスタンスで利用できる揮発性のストレージ
- 数百万IOPSを発揮でき、EBSよりも高いディスクパフォーマンスを発揮できる（EBSは256,000IOPS）

## ハードウェア占有インスタンス
### 共有ハードウェア
- 通常のEC2インスタンス購入オプション
- 他のAWSアカウントとハードウェアを共有する
### Dedicated Instance
- 特徴
  - インスタンス単位で契約
  - 同アカウントで起動している共有インスタンスが同時に稼働する場合がある
  - 物理的なCPUソケット、コア数、ホストIDは確認できない
  - BYOLをサポートしない
- 用途
  - ほかのAWSアカウントとは分離された専用ハードウェアでインスタンスを利用したい場合

### Dedicated Host
- 特徴
  - ホスト単位で契約
  - 他アカウントや共有インスタンスは同時に起動できない
  - 物理的なCPUソケット、コア数、ホストIDは確認できる
  - BYOLをサポートする
- 用途
  - 他のEC2インスタンスとは分離された専用ハードウェアで利用したい場合
[自分用メモ]Dockerコンテナのネットワーク設定

1. macvlan ネットワークの作成
```
docker network create -d macvlan --subnet=<サブネット> --gateway=<ゲートウェイ> -o parent=<親インターフェース> macvlan0
```

2. コンテナ起動時に macvlan ネットワークを指定
```
docker run -d --name <コンテナ名>  --network=macvlan0 --ip=<IPアドレス> <イメージ名>  sleep infinity
```
SAA 学習メモ VPC 関連

## ネットワークACL
- ネットワークアクセスをサブネットごとに制御するファイアウォール
- IPアドレスを元に許可ルールと拒否ルールの両方を設定可能
- ステートレスなファイアウォール
- ルールはユーザーが付与したルール番号の順に評価される
- ルール間で矛盾がある場合は小さい数字のルールが適用される

## CIDR
- VPCのCIDRに指定できるプレフィックス長は /16~/28
- AWSが推奨するIPv4アドレス範囲は以下
  - 10.0.0.0 ~ 10.255.255.255
  - 172.16.0.0 ~ 172.31.255.255
  - 192.168.0.0 ~ 192.168.255.255

## Egress-Onlyインターネットゲートウェイ
- NATGWとIGWの特徴を併せ持つ**IPv6専用**の機能
- VPCからインターネットの接続開始要求は通すが、インターネットからVPCへの接続開始要求は通さない
- 利用するには、プライベートサブネットのルートテーブルに、送信先が「::/0」、ターゲットが「Egress-Onlyインターネットゲートウェイ」となるルートを追加する

## ルートテーブル
- どのネットワークへデータを転送するかを定義する機能
- サブネットは1つのルートテーブルを関連付けることができる
- ルートテーブルが関連付けられていないサブネットは、VPC全体に適用されるメインルートテーブルにしたがってルーティングされる

## VPCエンドポイントポリシー
- VPCエンドポイントからの接続先を制限する機能
- ゲートウェイ型、インターフェイス型の両方で利用できる

## NATゲートウェイ
- プライベートサブネットからインターネットへ通信したいときに利用する**IPv4**専用の機能
- AWSによってAZ内で冗長化されている
- AZ障害時は利用できなくなるため、可用性を確保するには複数のAZにNATGWを配置する
Unity-Prefab Variantの親子の変更に対する相互作用のルール

# UnityのPrefab Variantにおける親子関係とオーバーライドの仕組み

UnityのPrefab Variantは、元のPrefab（親）を継承しながら独自の変更を加えることができる便利な仕組みです。本記事では、Prefab Variantの「継承とオーバーライド」のルールや、親と子の変更が競合した場合の優先順位について詳しく解説します。

---

## 1. Prefab Variantの「継承とオーバーライド」の仕組み
Prefab Variantは、元のPrefab（親）を継承しつつ、一部の要素を変更（オーバーライド）できます。基本的な動作ルールは以下の通りです。

### **📌 基本ルール**
| 操作 | 結果 |
|------|------|
| **親にスクリプトを追加** | **子にも自動的に追加される** ✅ |
| **子にスクリプトを追加** | **親の変更で上書きされない（子のオーバーライド）** ✅ |
| **子で親のスクリプトを削除** | **親が変更しても復活しない（オーバーライドが優先）** ✅ |
| **親でスクリプトを削除** | **子からも削除される** ✅ |


### **🛠 具体例**
#### **📌 例 1: 子に新しいスクリプトを追加**
```plaintext
1. ParentPrefab には何のスクリプトもなし。
2. VariantPrefab に Enemy スクリプトを追加。
3. ParentPrefab に CollisionHandler を追加。
➡  結果：VariantPrefab には「Enemy」と「CollisionHandler」が両方つく。
```
**→ 子で追加したスクリプトは親の変更で上書きされない！**

#### **📌 例 2: 子で親のスクリプトを削除**
```plaintext
1. ParentPrefab に CollisionHandler が最初からついている。
2. VariantPrefab で CollisionHandler を削除。
➡  結果：VariantPrefab には CollisionHandler がついていない（削除されたまま）。
```
**→ 子で削除したスクリプトは、親が変更しても復活しない！**

---

## 2. 親と子の変更が競合したときの優先順位
Prefab Variantで**子が変更（オーバーライド）した部分**に対して、親が同じ箇所を変更すると「競合（コンフリクト）」が発生します。この場合、**子の変更（オーバーライド）が優先される** のが基本ルールです。

### **📝 ルールまとめ**
| ケース | 結果 |
|------|------|
| **親が新しく要素を追加** | **子にも追加される** ✅ |
| **親が既存の要素を変更** | **子でオーバーライドしていた場合は無視される（子の変更が優先）** ✅ |
| **親が既存の要素を削除** | **子が変更していなければ削除されるが、オーバーライドしていた場合は残る** ✅ |


### **🛠 具体例**
#### **📌 例 1: スクリプトの値を変更した場合**
```plaintext
1. 親Prefab に Rigidbody があり、Mass = 1
2. 子Prefab で Rigidbody の Mass を 10 に変更
3. 親Prefab で Rigidbody の Mass を 5 に変更
➡ 結果：子Prefab の Mass は 10 のまま（子のオーバーライドが優先）
```
✅ **親の変更は子に適用されず、子のオーバーライドが保持される！**

#### **📌 例 2: 親で削除しても子で保持される**
```plaintext
1. 親Prefab に Rigidbody を追加
2. 子Prefab に Rigidbody が追加される（親の影響を受ける）
3. 子Prefab で Rigidbody を削除
4. 親Prefab で Rigidbody の Drag を 1 に変更
➡ 結果：子Prefab には Rigidbody がない（子で削除したため）
```
✅ **子で削除した場合、親の変更は無視される！**

#### **📌 例 3: Transform の変更**
```plaintext
1. 親Prefab の Position = (0,0,0)
2. 子Prefab で Position を (5,0,0) に変更
3. 親Prefab の Position を (10,0,0) に変更
➡ 結果：子Prefab の Position は (5,0,0) のまま（子のオーバーライドが優先）
```
✅ **Transform の変更も子のオーバーライドが優先！**

---

## 3. 親の変更を適用する方法：「オーバーライドをリセット」
もし親の変更を適用したい場合、**子Prefab のオーバーライドをリセット** すれば、親の変更を反映できます。

### **👀 方法（Unityエディタ上）**
1. **Prefab Variant の Inspector でオーバーライドされた項目を確認**
2. **変更を「右クリック → Prefab のオーバーライドを Revert」**
3. **親の変更が適用される！**

---

## **🎮 まとめ**
- **Prefab Variant は「親の要素 + 自分のオーバーライド」を持つ**
- **子でオーバーライドした箇所は親の変更の影響を受けない**
- **親が新しく追加したものは子にも反映される**
- **親の変更を適用したい場合は「オーバーライドをリセット」する**

この仕組みを理解しておけば、Prefab Variant を活用して柔軟なゲームオブジェクトの管理ができるようになります！ 🎮
[Linux][system][directory] 初期化システム_SysVinit, Upstart, systemd

# 初期化システム
- Linux システムの起動とプロセス管理を担う

# 初期化システムとその違い
| 項目 | SysVinit | Upstart | systemd |
|:--|:--|:--|:--|
| **起動方式** | - 直列起動 | - イベント駆動型<br>- 並列起動 | - 並列起動 |
| **設定ファイル** | - `/etc/inittab`<br>- `/etc/rc.d/` | - `/etc/event.d/`<br>- `/etc/init/` | - `/etc/systemd/system/`<br>- `/usr/lib/systemd/system/` |
| **起動速度** | - 低速 | - 中速 | - 高速 |
| **採用ディストリビューション** | - 旧型（RHEL 6以前） | - Ubuntu 9.10〜14.10 | - 新型（RHEL 7以降、Ubuntu 15.04以降） |
| **コマンド** | `service` | `initctl` | `systemctl` |
| **管理単位** | スクリプト | job | unit |
| **cgroups対応** | ❌ 非対応 | ⚠️ 限定的に対応 | ✅ 完全対応（リソース制御、階層管理など） |


# SysVinit
1. `init`の起動
    - `init`はカーネルによって`/sbin/init`が呼び出されて開始される
1. `init`の実行
    - `/etc/inittab`で、デフォルトのランレベルを確認する
1. ランレベルに応じたサービスの起動
    - `/etc/rc[0-6].d`または`/etc/init.d/`ディレクトリ以下の起動スクリプトで、システムのサービスを開始、停止、再起動する
1. プロセスのリリース管理
    - サービスやプロセスの管理は`PID`（プロセスID）を使用する
1. ログイン画面の表示
    - サービスがすべて起動した後、`init`はログインプロンプトを表示する

# systemd
1. `systemd`の起動
    - `systemd`はカーネルによって`/sbin/init`が呼び出されて開始される
1. `systemd`の実行
    - `/etc/systemd/system/default.target`で、デフォルトのターゲットを確認する
1. ターゲットに応じたUnitの読み込み・サービスの起動
    - `/etc/systemd/system`ディレクトリ以下のターゲットに応じたUnitの読み込み・サービスを起動する
    - （`systemd`は、依存関係を考慮して並列でサービスを起動する）
1. プロセスのリリース管理
    - サービスやプロセスの管理に`cgroup`（コントロールグループ）を使用する
1. ログイン画面の表示
    - サービスがすべて起動した後、`systemd`はログインプロンプトを表示します

# ランレベルとターゲット
||ランレベル|ターゲット|
|:--|:-:|:-:|
|対象初期化システム|init(SysVinit)|systemd|
|停止|0|poweroff.target|
|シングルユーザーモード|1/s/S|rescue.target|
|マルチユーザーモード<br>（テキストログイン）|2, 3, 4|multiuser.target|
|マルチユーザーモード<br>（グラフィカルログイン）|5|grafical.target|
|再起動|6|reboot.target|

# 参考リンク
- [Prepare for LPIC-1 exam 1 - topic 101.2: Boot the system](https://developer.ibm.com/tutorials/l-lpic1-101-2/)
- [Chapter 33. Boot Process, Init, and Shutdown](https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/5/html/installation_guide/ch-boot-init-shutdown#ch-boot-init-shutdown)

# Ping-t
SysVinit
- [3409_SysVinit, /etc/inittab](https://mondai.ping-t.com/question_subjects/31/question_sessions/32569047/progressing_questions/499039911)
- [3661_SysVinit, /etc/rc3.](https://mondai.ping-t.com/question_subjects/31/question_sessions/30553580/progressing_questions/468115703)
- [3010_SysVinit, /etc/inittab, ctrl+alt+del](https://mondai.ping-t.com/question_subjects/31/question_sessions/32527688/progressing_questions/498427177)

Upstart
- [3311_Upstart, systemd](https://mondai.ping-t.com/question_subjects/31/question_sessions/31585258/progressing_questions/483986847)
- [3312_Upstart](https://mondai.ping-t.com/question_subjects/31/question_sessions/31718661/progressing_questions/486071280)

systemd
- [3660_systemd](https://mondai.ping-t.com/question_subjects/31/question_sessions/30339661/progressing_questions/464809427)
- [3591_systemd, unit](https://mondai.ping-t.com/question_subjects/31/question_sessions/32569047/progressing_questions/499039892)
ExcelでQRコード作成

:::note warn
ActiveXオブジェクトは2025年4月から作成できなくなるようです。
こちらの作成法は使用できなくなるとのことで、ご注意ください。
:::

<iframe width="300" height="600" src="https://www.youtube.com/embed/eCHa0rw2Kuo" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
動画でも解説しました。

▽以下Microsoft365版のExcelでの設定です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3880604/002eaedd-d5b4-a91a-2177-c089f7f23134.png)
開発タブ➤挿入➤ActiveXコントロールの工具のアイコン(画像右下)を選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3880604/d719a8fe-07a7-cbe8-47b6-ef6dfa6657cb.png)
コントロールの選択ウィンドウで、Microsoft BarCode Control 16.0 を選択肢、OKをクリック。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3880604/f00fe2bb-551f-e630-10ee-0c53e5481a50.png)
カーソルが＋に変わるので、表示したい範囲を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3880604/2cf420e2-3c70-1739-7a34-1ab1213340bd.png)
プロパティで「LinkedCell」に連動したいセルを選択します。
ここで設定したセルに入力した文字列がQRコードになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3880604/de5ba47c-5248-f456-b776-e5efeec71587.png)
オブジェクトを右クリックして、
Microsoft BarCode Control 16.0 オブジェクト➤プロパティを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3880604/4c9862ba-2739-1384-fc6a-988c44cf34a0.png)
スタイルで「QRコード」を選んでOKをクリックすれば、設定は終了です。

あとは、LinkedCellで設定したセルに文字列を設定すれば、QRコードの出来あがりです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3880604/9495b16f-b4bc-ae25-3b37-f0f243a76b0d.png)

紙だと大きく印刷する分には問題ないと思いますが、小さく印刷すると読み取り精度が良くありませんでした。
プリンタの性能にもよると思います。

アイデア次第で色々使えると思いますので、ぜひ試してみてください。

※補足
Excelを開き直すと、オブジェクトを選択できなくなったりしてあせりますが、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3880604/8c52dc83-55db-657d-a690-db851c099bc4.png)
開発タブのデザインモードをオンにすることで、選択できるようになります。
AWSのElastic IPをEC2に関連付けてみた

# はじめに
AWSのElastic IPをEC2に関連付けしてみて気づいたこと。注意点を本記事にまとめます。

### 前提条件
EC2 2台構築済み

参考記事
コンソール上の操作
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/working-with-eips.html
https://qiita.com/Jerid/items/d5dd3a29ed9a0e374493
CLI
https://qiita.com/cmdbean/items/27e46431785f3cff3bee

## 手順　コンソール

### 1.Elastic IPが既に存在する環境の場合は、スクリーンショットを取得する
作業前に誤って別のEC2インスタンスとElastic IPを関連付けてしまうリスクを防ぐためです。
※スクリーンショットを証跡として残すことで、作業前の状態を正確に記録することが出来ます。

### 2. Elastic IPを作成する手順
サービス >> EC2 >> 左ペインのElastic IPをクリックする
「Elastic IPアドレスを割り振る」をクリックする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599002/5d0d077d-c3ac-99e2-5c7c-e588fcfc4b14.png)

今回は、ネットワークボーダーグループとして 東京リージョン（ap-northeast-1）を選択します。
Elastic IPアドレスを作成した後に用途が分からなくならないよう、Nameタグを付与することをお勧めします。
**タグを活用することで、Elastic IPアドレスの管理がしやすくなり、誤った使用を防ぐことができます。**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599002/c557aa93-5644-db23-a79b-d1cd9089deee.png)

#### Elastic IPを作成されました

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599002/afe10a89-9e01-c306-3a5c-4bddd397963a.png)

### 3. EC2に関連付けます
対象のElastic IPアドレスにチェックを入れてアクションから「Elastic IPアドレスを関連付けする」を選択する。
 注意点:
アクション選択時に手が当たって誤って 「Elastic IPアドレスを解放」 を選択してしまっても、最終確認画面が表示されるため、その画面で「解放」を選択しなければ影響はありません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599002/1a5c3f84-5cb5-04ef-9fd8-aaca26ac04ca.png)


この画面では最終確認画面となるため画像のスクリーンショットを取得することをお勧めします。
①対象のEC2を選択する。
②①で選択したEC2のプライベートIPアドレスを選択する。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599002/9d6b665e-cb55-755b-2903-71bbaf4cb1e8.png)

※EC2インスタンスには、 1つのプライマリプライベートIPアドレスだけでなく、 複数のセカンダリプライベートIPを割り当てることが可能です。そのため、Elastic IPの画面では一つのプライベートIPアドレスを指定しております。


**すでに Elastic IPアドレスを関連付けているEC2インスタンスに誤って新しいElastic IPアドレスを関連付けると、即座に現行のElastic IPアドレスが解除され、新しいElastic IPアドレスが関連付けられてしまいます。**
そのため、コンソールは誤った選択をする可能性があるため、CLIの方が安全のケースもあります。

**再関連付けとは**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599002/cef654d7-ca06-7c01-cb59-b52c45735afc.png)

EIP-1を作成時に再関連付けをチェックなしの場合
EC2-A に EIP-1 が関連付けられている状態で、EIP-1を EC2-B に関連付ける場合はエラーが出ます。

EIP-1を作成時に再関連付けをチェックありの場合
EIP-1 はEC2-Aから解除され、EC2-Bに移動されます。

※本番環境の場合は再関連付けにチェック外すことをお勧めします。


## 手順　CLI
cloudshellにてログインして
以下のコマンドを実行して、Elastic IPをEC2に関連付けてみました
```
aws ec2 associate-address --allocation-id {allocation-id　※割り当て ID} --instance {instance-id}
```
```
例) aws ec2 associate-address --allocation-id eipalloc-0d8xxxxxxxxxx --instance i-07xxxxxxxxxx
成功したら関連付け IDが表示されます
{
    "AssociationId": "eipassoc-xxxxxxxxxx"
}
```
TEST1のEC2にElastic IPが割り振られました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599002/1a733f73-e5a8-0cd0-c012-c66f9a16856b.png)

Elasitc IPの関連付けを外しました。
```
aws ec2 disassociate-address --association-id {association-id※関連付け ID}

例) aws ec2 disassociate-address --association-id eipassoc-xxxxxxxxxx
正常終了時に結果は何も表示されません。エラーの場合はエラー文が出る可能性があります。
```

普段、割り当てID や 関連付けID を意識することは少ないため、CLIで操作する際は IDの取り違えに十分注意が必要です。

# まとめ
Elastic IPをEC2に関連付ける操作は慎重な操作が必要になります。
この記事に注意点を記載しました。参考にしていただければ幸いです。
[ODC]Timer実行中のSetting変更が反映されない

ODCで、運用中に変更できるアプリケーションの設定値はSettingに持つ。
OutSystems11で言うと、Site Propertyにあたる（Site Propertyと違いプログラムから変更することはできない）。

Timerの実行を運用者が強制中断できるようにしたいと思い、以下のプログラムを用意して実験してみたら意外な結果になったのでメモ。

- SettingにBoolean型の値を用意しておく
- TimerからSwitchの値を参照し、ログに出力する

# 環境情報
ODC Studio(Version 1.5.8)

# Timer実行中に変更されたSettingの値は、実行中には古い値しか見えない
## 動作確認イメージ
- Boolean型のSettingを用意（デフォルトFalse）
- Timerを2つ用意し、両方でこのSettingの値をLogMessageでODC Portal > Logsに出力
- Timer実行中に行ったSettingの変更を確認するため、SettingをLogMessageで出力　→　(System)Sleepで90秒スリープ　→ Settingをもう一度LogMessageで出力というロジックにした
- リトライ時の動作を確認するため、必ずタイムアウトが発生するように、TimerのTimeout in Minutesを短く設定する
- Timer1を開始した後Settingの値をFalse → Trueに変更（図中の赤い線のタイミング）
- Settingの値を変更後、Timer2を開始
![スクリーンショット 2025-02-11 20.24.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/c0ec1afe-4d1f-6407-f75a-9c1bd9122aaf.png)

## 確認結果
動作確認イメージの図に示した①〜④のタイミングで出力されたログを確認したところ以下の通り。

|  | Settingの値 | タイミングの説明 |
|:-:|:-:|:-|
| ① | False  | Setting変更前  |
| ② | False  | Timer実行開始してから、Settingを変更した後  |
| ③ | False  | Timerがタイムアウトにかかってリトライ  |
| ④ | True  | Settingの値を変更後に、（リトライでなく）新たに開始したTimer  |

以上から、以下の結果となった。1、2共に意外で、不都合のある動作。
1. Timer実行を開始した時点で、利用するSettingの値は固定され、実行中に変更された後の値は参照できない
2. リトライした場合でも、最初の実行開始時点のSettingの値を使う
3. リトライでなく、新たに開始したTimerは変更後の値を参照できる

# 本当はやりたかったができなくなること
Timerは長時間実行するが、強制的に実行を停止する方法がない。
さらにタイムアウトすると、勝手にリトライを行なってしまう。

そのため、Settingでスイッチを設け、実行を強制停止できるようにロジックを組んでおきたい。
OutSystems11の頃は安全策としてこういう実装を組む手もあった。

# Data Actionの実行中に行ったSetting変更も、実行中には見えない
Timer以外の要素の場合はどうかと思って、Data Actionでも試してみた。
Server Request Timeoutを60秒に設定し、LogMessageでSettingの値を記録　→ 40秒Sleep → もう一度LogMessageでSettingの値を記録、と言うロジックを利用。
Sleep中にODC PortalからSettingの値を変更してみたが、2回のLogMessageは共に変更前の値をログに記録した。
![スクリーンショット 2025-02-11 21.11.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/43071a74-ccb7-84de-6677-bc5adc9f649a.png)

つまり、Timerに限らず、ある要素の実行開始後に行われたSetting変更は、その実行中は見えない（古い設定値が見える）と言うことに見える。

これも若干意外な結果ではあるが、長時間実行を想定するTimerと違い、他の要素は次回実行時に変更後の設定値で動作すれば十分なことは多そうに思える。
初めてのreact

## header要素を変更する
react-helmetのようなものが必要だったらしいがreact19からは要らないらしい
returnの中にheader要素のタグを書くだけ
例）title
```
function App() {
return (
<title>タイトル名</title>
);
}

export default App
```

## ルーティング
react routerを使用する
インストール
```
npm i react-router
```
使い方
```
import React from "react";
import ReactDOM from "react-dom/client";
import { BrowserRouter, Routes, Route } from "react-router";
import App from "./App";
import About from "./About";
import Explain from "./Explain";
import NotFound from "./NotFound";
import Layout from "./Layout";

const root = document.getElementById("root");

ReactDOM.createRoot(root).render(
  <BrowserRouter>
    <Routes>
      <Route path="/" element={<Layout />}>{/* ←親要素 */}
        {/* Layout.jsxの中に<Outlet />を書くと下記のネストされているものが表示される */}
        <Route index element={<App />} />{/* ←子要素（/で表示される） */}
        <Route path="about" element={<About />} />{/* ←子要素（/aboutで表示） */}
        <Route path="explain" element={<Explain />} />{/* ←子要素（/explainで表示） */}
      </Route>
      <Route path="*" element={<NotFound />} />{/* ←ワイルドカードはどこにも入らなかったとき */}
    </Routes>
  </BrowserRouter>
);
```

## 共通のレイアウト
ルーティングの所と被るが、親要素に共通のコンポーネントを設定しておき、子要素にそれぞれの要素を入れる。
```
import './css/Layout.css';
import { NavLink, Link, Outlet } from "react-router";

function Layout() {
    return (
      <div>
      /***********共通で使用**************/
        <header>
          <nav>
            <NavLink to="/" activeClassName="active">Home</NavLink>
            <NavLink to="/about" activeClassName="active">About</NavLink>
            <NavLink to="/explain" activeClassName="active">Explain</NavLink>
          </nav>
        </header>
        /***********共通で使用**************/
        <main>
          <Outlet />　<-ここに子要素が入る
        </main>
        /***********共通で使用**************/
        <footer>
          <p>© 2025 My Website</p>
        </footer>
        /***********共通で使用**************/
      </div>
    );
  }
  
  export default Layout;
```

## props state hooks
自分用VB.netメモ

### .Substring(A,B)
AからB文字を抽出する
Aだけの場合はAから最後まで
<Br><Br>
### `Trim()
前後の空白文字を削除
`.TrimStart`先頭の空白文字を削除
`.TrimEnd`末尾の空白文字を削除
<Br><Br>
### .IndexOf(A)
文字列のAと重複する位置を返す（何文字目か）
空白文字（""）を指定した場合は0を返す
見つからないと-1を返す
<Br><Br>
### New String(A,B)
A: 繰り返す文字（キャラクター）。
B: その文字を繰り返す回数。
この構文は、指定した文字を指定した回数繰り返した文字列を生成します。
<Br><Br>
### .Length
文字列の文字数を返します。
文字列に含まれる文字、空白、句読点などもすべて「1文字」としてカウントされます。
<Br><Br>
### Integer.Parse(A)
Aを整数型にへんかん
String　文字列
Double　小数点
Date　日付
Decimal　より精密な小数点

エラーへの対処
Tryparse(A,B)
AをBの型に変換してBに入れる
<Br><Br>
<Br><Br>
<Br><Br>
Session Storageの使用用途と使用方法

## はじめに
Webアプリケーションを開発していると、ユーザーごとに一時的な情報を保存する必要が生じる場合があります。そこで活躍するのが**sessionStorage**です。本記事では、sessionStorageの基本的な機能や使用方法、注意点についてまとめてみようと思います。

## SessionStorageとは
sessionStorageは、ブラウザ上でタブやウィンドウ単位でデータを保存できる仕組みです。  
localStorageとの大きな違いは、sessionStorageに保存されたデータは、ブラウザのタブまたはウィンドウが閉じられると自動的に削除される点にあります。
使用用途としては、異なるページ間でユーザーの選択情報を一時的に保持する(ユーザーがフォームを入力していく際に誤って、前のページに戻ってしまっても入力情報を記録する)といった例が挙げられます。

## 基本的な使い方

### 1. データの保存
sessionStorageにデータを保存するには、`setItem`メソッドを使用します。

```javascript
// キー「username」に値を保存
sessionStorage.setItem('username', 'hoge');
```
### 2. データの取得
保存したデータを取得するには、getItemメソッドを使用します。

```javascript
// キー「username」の値を取得
const username = sessionStorage.getItem('username');
console.log(username); // 出力: hoge
```

### 3. データの削除
特定のデータを削除するには、removeItemメソッドを使用します。

```javascript
// キー「username」のデータを削除
sessionStorage.removeItem('username');
```
### 4. セッション全体のクリア
全ての保存データを一括で削除する場合は、clearメソッドを使用します。

```javascript
// セッション内の全データを削除
sessionStorage.clear();
```
## 注意点
・sessionStorageに保存されたデータは、ブラウザのタブまたはウィンドウが閉じられると削除されてしまう
・session storageに保存した情報は簡単に取られてしまうので、機密情報を保存しては行けない


## まとめ
sessionStorageは、一時的なデータの保存に非常に便利なAPIです。
フォーム入力の一時保存、あるいはページ間でのデータ受け渡しの際にとても便利なものになります。ですが、簡単に情報を抜き取られてしまうため、使用には注意が必要です。
kintoneのファイルアップロードの実装で詰まった記録

はじめまして！！ノベルワークス入社2年目のそうま([@SomaActionPlan](https://x.com/SomaActionPlan))です！！

今日は、kintoneRestAPIを利用した添付ファイルアップロードの実装で詰まった点を備忘録として残そうと思います！！

https://cybozu.dev/ja/kintone/docs/rest-api/

# 前提
kintoneには添付ファイルフィールドというフィールドタイプが存在し、さまざまな形式のファイルをアップロードし保存する事が出来ます。

このフィールドにファイルをアップロードするAPIが存在するので、それを使用します。

![添付ファイル-説明.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1100170/1c94972a-0cd1-6341-a36a-d46d2e6062ca.png)

https://jp.cybozu.help/k/ja/user/app_settings/form/form_parts/attachment.html

https://cybozu.dev/ja/kintone/docs/rest-api/files/upload-file/

# 詰まった点其1 - Blobオブジェクト
まず最初に、ファイルをアップロードする前に一度ファイルの内容をMIMEタイプを指定して`Blob`オブジェクトに変換する必要がある点を理解できずに詰まりました。

:::note info
MIMEタイプ
ファイルの形式や性質を表す種別。
例) jpeg拡張子 -> `image/jpeg` 
:::

:::note info
Blobオブジェクト
読み取り専用のバイナリーデータを保持するオブジェクト。
https://developer.mozilla.org/ja/docs/Web/API/Blob
:::

blobの作成自体は、以下のコードで実装できました。
```js
const blob = new Blob([<任意のファイル内容>], { type: <任意のmimeType> });
```

# 詰まった点其2 - ファイルキーの取得
次にファイルキーの取得までに中々時間がかかってしまったので、以下に手順を残します。

## フォームデータの作成

まず初めにフォームデータを作成します。

:::note info
フォームデータ
webフォームから送信するデータ形式の1つ、キーと値のペアを持つ
https://e-words.jp/w/%E3%83%95%E3%82%A9%E3%83%BC%E3%83%A0%E3%83%87%E3%83%BC%E3%82%BF.html
:::

```js
const formData = new FormData();
```

先程作成した `Blob` オブジェクトを `file` をキーにしてフォームデータに追加します。

```js
formData.append("file", blob, <任意のファイル名>);
```

ファイルをアップロードする際、CSRFトークンが必要みたいなので、`kintone.getRequestToken` を使用しトークンを作成します。

:::note info
CSRFトークン
webアプリケーションがセッションごとに発行するトークン
:::

```js
const requestToken = kintone.getRequestToken()
```

https://cybozu.dev/ja/kintone/docs/js-api/api/get-csrf-token/

生成したトークンを `__REQUEST_TOKEN__` をキーにしてフォームデータに追加します。

```js
formData.append("__REQUEST_TOKEN__", requestToken);
```

これでフォームデータは完成です！

## ファイルアップロード

ファイルアップロードAPIでは、kintone REST APIを実行するための関数である`kintone.api()`を使用出来ないので `fetch` APIを使用します。

これに気づくのが遅れてしまい少し詰まってしまいました...。

先程作成した フォームデータを以下のように `body` に指定します。

```js
const headers = {
    "X-Requested-With": "XMLHttpRequest",
};

const response = await fetch(`https://<kintoneのサブドメイン>}/k/v1/file.json`, {
    method: "POST",
    headers,
    body: formData,
});
```

これでファイルアップロードが完了し、ファイルキーを取得できます！

# 詰まった点其3 - ファイルキーとレコードの紐付け
まず最初に、ファイルアップロードのAPIを使用してファイルをアップロードした時点で、そのままレコードにも保存されるものだと思っていました。

そうではなくレコードへの保存には以下のステップが必要でした。
1. ファイルを一時保存領域に保存する
1. ファイルキーを取得する
1. 発行したファイルキーを対象のレコードに保存する

![添付ファイル-説明.drawio (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1100170/0f56e939-1b92-821d-dd0a-06188add7605.png)

先程のファイルアップロード時に取得したレスポンスデータにファイルキーが存在するので、そのファイルキーを以下のようにしてレコードに保存します。

```js
const fileKey = (await response.json()).fileKey;

const record = {
    <対象の添付ファイルフィールドのフィールドコード> : {
        value: [
            {
                fileKey,
            },
        ],
    },
};

const body = {
    app: <対象のアプリID>
    id: <対象のレコードID>
    record,
};

await kintone.api(kintone.api.url("/k/v1/record.json", true), "PUT", body);
```

これでレコードへファイルの保存が完了しました！！

# 纏め
添付ファイルフィールドの更新は、他のフィールドと違い少し手順を踏む必要があるという事を理解できました！今後の実装に役立てていこうと思います！
『すべての仕事は10分で終わる』を読んで、目標達成のヒントを得る


## 自己紹介

紅茶犬（TeaDog）と申します。
<details>
元々、不動産管理でマンションやビル管理の運用サポートをしておりました。
会社のプロジェクトでECサイトを開設することになり、エンドユーザーとして開発に携わりまして、エンジニアおもろいなーで、なんやかんやあって会社を退職。職業訓練・エンジニアスクールを経てSESに入社。開発エンジニアを2年経験し、現在の会社に社内SE（情シス）として入社しました。

会社のシステム担当は2名で、その内の1名が直属の上司となりました。

2名ともメインフレームを主戦場に戦ってきた大ベテランで、
webやコーディング等の技術相談は出来ませんが、壁打ち相手になっていただいたり、
圧倒的経験値から滲み出る濃厚なアドバイスをいただけたりと、日々成長させてもらってます。

Pythonでシステムやバッチを開発したり、PADでRPAしたり、キッティングやバックアップ用のシェルを書いたり、
SaaSを導入したり、各営業店の配線工事、OA機器の入替、動画編集、リクルート等々...色々好き勝手やらせてもらってます。

１年やってきましたが、システム担当2名は嘱託であと3年以内には居なくなり、システム責任者に否が応でもならなくちゃいけないので、ぼちぼち情シス領域のインプットを始めようと考え始めました。
初めに、以下記事で紹介されている書籍を読んでみることにしました。せっかくなのでアウトプットも練習。

https://r35-se.com/archives/822


情シス・社内SEの諸先輩方。是非勉強させていただきたいので繋がってくださいませ...
X: @McDo_Donga

また、情シス・社内SEのコミュニティについても情報があればご教授いただけますと幸いです。
情シスSlackは参加しています。毎日眺めるだけでも勉強になります。感謝。

</details>

## 『すべての仕事は10分で終わる』を読んでみました。 
5時間で読了。エッセンシャル思考主義みたいな本でした。１～３年目の社会人が悩んだ時に読んだら良質なヒントになりそうですね。

### ◆感想とかキーワードとか乱文etc

◎日頃から情報の整理
→　調べたものをデータ化し、いつでもアウトプットできる状態にする
→　調べなおさなくてもいいし、脳内整理にもなる。速攻で根拠も出せるし。


◎10分で区切る　※自己解釈含む
仕事を「ジョブ」「タスク」に区別する。
・ジョブ - 頭を使う仕事　...　考える時間を確保し確実に処理する。
・タスク - 作業　...　考える時間を確保するために

１．仕事（タスク）を10分単位で整理する。
（10分で仕事を終わらせる。ということではない）

２．大きな仕事（タスク）でも10分で終わるように分解する。
（手順で分解、カテゴリ化で分解）

３．１～２で作成した10分タスクはスケジュールに落とし込むことで、工数が明確化できるし、日中のちょっとした空き時間があればタスクを処理することも可能。
（事前に10分で終わるとわかっていれば着手もしやすいですね。）

４．10分タスクであれば、同僚や部下に仕事も降りやすい。整理済みなので指示コストも低い。

５．タスクを高速で処理することで、ジョブに使う時間を増やすことができる。
（＝考える時間が増えるため、質のいいアウトプットが出せる。）

【課題】10分の精度を高める
10分で収まらなかった場合、精度を高める必要がある。
精度を高める方法は「作業時間のログ化」と「振り返り」

【発見】プライベートのTODOを仕事のTODOと並行して書く
TODOリストを「ジョブ」「タスク」で分類し、さらにタスクは情報整理のためカテゴリ分けをしているそう。
カテゴリには仕事関係以外にもプライベート関係も存在するそうです。
時間管理の視点から、仕事も、プライベートも、一緒であるのが自然という観点。
TODOリスト ... 自分が起きている時間を何に使うか？を明記したもの

→　私は、年間の目標、月間の目標を作成し毎月自己レビューを行っていますがプライベートの目標達成率が低く、課題と感じていました。この観点であれば達成率上がりそう。詰めて作業しすぎないように気を付けてぼちぼちやっていこ。

◎人を巻き込むときは設計図を先に描く
新規プロジェクトや会議の場合は具体的イメージを持って挑むこと。
・期日
・必要なこと（フェーズ、仕事）
・担当者の想定
・各連携

→　不動産管理会社時代に、毎週マンションで理事会・総会をガシガシ開催していたのでこのあたりは鬼共感。ゴールや目的をすり合わせる作業大切！

◎「バタバタ案件」は手順をマニュアル化
トラブルに対応した時間や手順を振り返り、マニュアル化する。
おおよその処理時間が見えるし、トラブルシューティングをマニュアル化することで、同僚・部下に対応を振ることができる。
→　この仕事をやっていると「バタバタ案件」に振り回されることは多いです。緊急性も高いので仕事のスケジュールが崩れるため、残業が増えがち。マニュアル化やってみます。


### 最後に
他は、既に取り入れていたり同じマインドだったりしたので割愛。
名著『7つの習慣』についても触れていていました。興味出ました。読んでみたいなー。
乱文ですみません。また時間とって修正していきます。
"Failure/Error: require 'rspec/rails' "と出たのでRSpecの設定を見直してみた

# はじめに
RSpecのテストを実行したら、下記のエラーが出ました。
`require 'rspec/rails'`は設定ファイルに明記しているのになぜ？
```
Failure/Error: require 'rspec/rails'
```

# 原因
**`rails_helper.rb` の読み込み順序が誤っていました**。
当たり前ですが、**上から順に設定ファイルの内容が読み込まれていきます**。
従って、下記に気を付ける必要があります。

***・テスト環境の設定 `ENV['RAILS_ENV']`は、Rails環境が読み込まれる前に行う
・Rails環境 `config/environment`は、RSpecの設定より先に読み込む
・RSpec関連の設定は、Rails環境が準備された後に行う***
***
**～修正前～**

順序がぐちゃぐちゃですが載せておきます。。もちろんこれだと動きません。
```rb:rails_helper.rb

require_relative '../config/environment'
# rspec-rails を使用するための設定
require 'spec_helper'
# 本番や開発データベースを使用しないようにするための設定
ENV['RAILS_ENV'] ||= 'test'
# Rails の環境をテストモードに設定
require File.expand_path('../config/environment', __dir__)

# RSpec の実行環境が production になっていないかチェック
abort("The Rails environment is running in production mode!") if Rails.env.production?

require 'rspec/rails'

# （FactoryBot）spec/support ディレクトリ内のすべてのファイルを読み込む
Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }

begin
  ActiveRecord::Migration.maintain_test_schema!
rescue ActiveRecord::PendingMigrationError => e
  abort e.to_s.strip
end
RSpec.configure do |config|
  # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
  config.fixture_path = Rails.root.join('spec/fixtures')
  # FactoryBot を使用するための設定
  config.include FactoryBot::Syntax::Methods
  # テストが DB を変更した場合にリセットする設定（RSpec の transactions を使用）
  config.use_transactional_fixtures = true
  config.infer_spec_type_from_file_location!

  # Filter lines from Rails gems in backtraces.
  config.filter_rails_from_backtrace!
  
  # 不要な `should` の警告を抑制
  config.expect_with :rspec do |expectations|
    expectations.syntax = :expect
  end
end
```

**～修正後～**
```rb:rails_helper.rb
# 本番や開発データベースを使用しないようにするための設定
ENV['RAILS_ENV'] ||= 'test'
# Rails の環境をテストモードに設定
require File.expand_path('../config/environment', __dir__)

require 'rspec/rails'
# rspec-rails を使用するための設定
require 'spec_helper'
require_relative '../config/environment'

# RSpec の実行環境が production になっていないかチェック
abort('The Rails environment is running in production mode!') if Rails.env.production?

# （FactoryBot）spec/support ディレクトリ内のすべてのファイルを読み込む
Dir[Rails.root.join('spec/support/**/*.rb')].sort.each { |f| require f }

begin
  ActiveRecord::Migration.maintain_test_schema!
rescue ActiveRecord::PendingMigrationError => e
  abort e.to_s.strip
end
RSpec.configure do |config|
  # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
  config.fixture_path = Rails.root.join('spec/fixtures')
  # FactoryBot を使用するための設定
  config.include FactoryBot::Syntax::Methods
  # テストが DB を変更した場合にリセットする設定（RSpec の transactions を使用）
  config.use_transactional_fixtures = true

  # テストが失敗した場合にスクリーンショットを撮る設定
  config.infer_spec_type_from_file_location!
  config.filter_rails_from_backtrace!

  # 不要な `should` の警告を抑制
  config.expect_with :rspec do |expectations|
    expectations.syntax = :expect
  end
end
```

# おわりに
これまではたまたま正しい順序で記載されていたから動いてくれていたものの、設定を何かしら変更した影響で順序もおかしくなっていたようです。
THE初心者なミスですが、学びになりました。
初心者によるメモ(アルゴ式、「無駄のない九九」)

## 問題
ロジック実装初級

https://algo-method.com/tasks/f8050725813f22a5

## 考察
二重ループで実装する。その際jの添字をiスタートにすればよい
## ACコード
```py
for i in range(1,10):
    for j in range(i,10):
        print(i *j,end = " ")
    print()
```
行列連鎖積問題をPythonで解いてみた(動的計画法)

# はじめに
こんにちは！今回は動的計画法(Dynamic Programming)を使って行列連鎖積問題(Matrix Chain Multiplication)を解くプログラムを紹介します。
# 行列連鎖積問題とは？
行列A1,A2,....,Anが与えられたとき、これらを掛け合わせる順序によって計算量が変化します。行列の掛け算は結合法則が成り立つため、計算結果は変わりませんが計算回数が最小となる括弧の付け方を求めるのがこの問題です。
例えば、行列の次元が以下のような場合を考えます。A1(13×30),A2(30×8),A3(8×4),A4(4×41)これらを掛ける順序によって、掛け算の回数は大きく変わります。
# 実装コード
以下がPythonで実装したコードです。動的計画法を用いて、最小の掛け算回数を計算し、最適な括弧付けを出力します。
```py:mcm.py
def matrix_chain_order(dimensions):
    n = len(dimensions) - 1
    m = [[0] * n for _ in range(n)]
    s = [[0] * n for _ in range(n)]
    parens = [[f"A{i+1}" for i in range(n)] for _ in range(n)]

    for l in range(2, n + 1):
        for i in range(n - l + 1):
            j = i + l - 1
            m[i][j] = float('inf')
            for k in range(i, j):
                q = m[i][k] + m[k + 1][j] + dimensions[i] * dimensions[k + 1] * dimensions[j + 1]
                if q < m[i][j]:
                    m[i][j] = q
                    s[i][j] = k
                    parens[i][j] = f"({parens[i][k]}{parens[k+1][j]})"
    return m, s, parens

def print_optimal_parens(s, i, j):
    if i == j:
        print(f"A{i+1}", end="")
    else:
        print("(", end="")
        print_optimal_parens(s, i, s[i][j])
        print_optimal_parens(s, s[i][j] + 1, j)
        print(")", end="")

# 使用例
dimensions = [13, 30, 8, 4, 41]
print("行列の次元:", dimensions)
m, s, parens = matrix_chain_order(dimensions)
print("\n最適な括弧付け:")
print_optimal_parens(s, 0, len(dimensions) - 2)
print("\n最小の乗算回数:", m[0][len(dimensions) - 2])
```
# アルゴリズム解説
このプログラムは動的計画法を用いてm[i][j]に「行列AiからAj」までの最小乗算回数」を格納します。
### 計算手順
① m[i][j]の初期化
 - m[i][i]=0 (1つの行列の場合、掛け算は不要)

② 鎖の長さ(l) を増やしながら最小値を更新
 - l=2 からnまでループし、すべての部分問題を解く

③ 再帰的に括弧を付ける
 - すべてのKを試して最小の計算回数を見つける
 
→計算量はO(n^3)ですが、nが大きくなると直接計算するより圧倒的に速くなります。
# 実行例
次のような入力の場合、最適な括弧付けと最小の乗算回数が計算されます。
```
行列の次元: [13, 30, 8, 4, 41]

鎖の長さ 2:
m(0, 1):
    (A1)(A2) : 0 + 0 + 13*30*8 = 3120
    m(0, 1) = 3120
m(1, 2):
    (A2)(A3) : 0 + 0 + 30*8*4 = 960
    m(1, 2) = 960
m(2, 3):
    (A3)(A4) : 0 + 0 + 8*4*41 = 1312
    m(2, 3) = 1312

現在の状態:
          0       1       2       3
   --------------------------------
0: |      0    3120       0       0 | 13x30
1: |      0       0     960       0 | 30x8
2: |      0       0       0    1312 | 8x4
3: |      0       0       0       0 | 4x41


鎖の長さ 3:
m(0, 2):
    (A1)((A2A3)) : 0 + 960 + 13*30*4 = 2520
...
((A1(A2A3))A4)
最小の乗算回数: 4652

最終的な括弧付け表現: ((A1(A2A3))A4)
```
# まとめ
行列連鎖積問題を解くことで、アルゴリズム設計の基本的な考え方である「動的計画法」の理解が深まります。今回のプログラムを活用し、より大規模な行列計算や関連問題に応用してみてください。最後まで読んでくださり、ありがとうございました。もし改善点や質問があれば、ぜひコメントしてください！
テキストが改行されずに横に続く方法

# whitespace-nowrapを使う
Tailwind CSS の whitespace-nowrap を適用すると、テキストが改行されずに横に続く ようになります。

# 効果
改行 (\n) が無視される（1行のまま表示）
セルの幅を超えると横スクロールが発生する
レイアウト崩れを防ぐには truncate や overflow-auto を追加するのがベター

# コード
```
<table class="whitespace-nowrap">
```
【イベントレポート】M365セキュリティ&ゼロトラスト勉強会 22 #m365sec

いつも記事を読んでいただきありがとうございます！
モブエンジニア（[@mob-engineer](https://qiita.com/mob_engineer))です！

今回は2025.02.11（火）に開催した**M365セキュリティ&ゼロトラスト勉強会 22**へ参加しましたので、アウトプットとしてイベントレポートを執筆しました。

初学者でもサクッと読めるように平易な表現で執筆しておりますので、お気軽に読んでいただければ幸いです。

#### イベントページ

https://m365security.connpass.com/event/341634/

## 目次
- イベントレポート
    - 自己紹介
    - アジェンダ
    - Microsoftデジタル防衛レポート2024
    - 生成AI関連
- まとめ

## イベントレポート

### 自己紹介
- アンド・キャピタルパートナーズ所属の方
- ISACA東京支部の副会長などのコミュニティ活動もされている方

### アジェンダ
- Microsoftデジタル防衛レポート2024を読んでいく

### Microsoftデジタル防衛レポート2024

#### 参考サイト

https://www.microsoft.com/ja-jp/security/security-insider/intelligence-reports/10-essential-insights-from-the-Microsoft-Digital-Defense-Report-2024

https://www.microsoft.com/ja-jp/security/security-insider/intelligence-reports/microsoft-digital-defense-report-2024

https://www.ipa.go.jp/security/10threats/10threats2025.html

https://atmarkit.itmedia.co.jp/ait/articles/2005/12/news003.html

https://www.nisc.go.jp/pdf/news/press/20250204_ddos.pdf

https://www.cas.go.jp/jp/seisaku/cyber_anzen_hosyo_torikumi/index.html

- Microsoftデジタル防衛レポートは英語でとっつきづらい
    - とりあえず分かった気になることが重要
    - シェアしながら相互理解していくことが重要
    - （余談）次回は**Microsoftセキュリティ露出管理を学んでいく**
- 前提として2023/07～2024/07のセキュリティトレンドを取り扱っている
    - 直近のトレンドは含まれていない
    - Microsoftとしてもセキュリティ対策に関しては力を入れている
- AIを用いた攻撃
    - AIが台頭したときは日本語が怪しいなどの見抜きポイントがあった
        - 現在はAIが進歩したため、見抜くことが難しい
- セキュリティ攻撃の情報源
    - IPAから**情報セキュリティ10大脅威 2025**が発表されている
- Microsoftトレンド
    - DDoS攻撃が特に多く取り上げられていた
    - 正しいパケットかどうかを見抜く必要がある
    - 株コム時代にDDoS被害でサービス影響があった
        - その経験がDDoSへの対策理解につながった
- 能動的サイバー攻撃
    - 日本経済新聞でも取り上げられている
    - 閣議決定の資料を見てみると、官民連携で進めていく
- 本編（Microsoftデジタル防衛レポート2024）
    - 第1章・第2章以降は生成AI関連が大半
    - 第1章：セキュリティ被害の状況
        - 詐欺被害の中で最も多いのはテックサポート詐欺
            - ざっくり言えば、フィッシングサイトによる詐欺
    - 第2章：サイバーセキュリティへの戦略的アプローチ
        - シャドーITの撲滅、官民連携（能動的サイバー防御）の話が示されている
    - エグゼクティブサマリー
        - （余談）翻訳ツールって選ぶのが難しい...
        - 技術は進歩しているが、セキュリティ被害は減少していない
            - セキュリティに強い人材は少ない状況（特に中小企業）
        - 1日あたりのセキュリティ被害は1万件以上
        - 各国のサイバー視点もレポートにまとめられている
            - ISMAPなどの話
        - セキュリティ被害に関してもまとめられている
            - ランサムウェア、テック系詐欺など
        - アイデンティティ攻撃に関しては99%以上がパスワード攻撃
- 組織のセキュリティ
    - 技術的負債とシャドーITへの取り組みを語っている
        - 未使用テナントの削除など
    - 自分の家を管理するかのように進めていく
        - Microsoftとしても製品販売だけでなく、データ保護の取り組みを行っている
            - ラベル付けなど
- 生成AI活用論
    - Microsoft的には責任あるAIを実現することが重要
    - AIを活用してナレッジ収集、優先付けを行うことも大切
    - ルールベースのアプローチから生成AIベースのアプローチへ変わっていく

### 生成AI関連
- ChatGPT Assistant
    - RAGを活用して最新情報を生成AIに学習させる
- DeepSeekに関する
    - データ取り扱いなどに関していくつか疑問があるが
    - Microsoft Defenderで生成AIを制御できる
- ChatGPT Pro/Deep Research
    - Proプランでないと利用出来ないが、図表を含めたレポートを生成してくれる
    - リサーチ内容も確認することが出来る
    - 推論を通じてハルシネーション潰しを行っている
    - リンクを共有すれば、他ユーザもプロンプトを追加できる

## まとめ

Microsoftデジタル防衛レポート2024に関してキャッチアップを行えていなかったのですが、本勉強会を通じて、本レポートが何を伝えたいのかをキャッチすることが出来ました。

そのうえで、本セッションで得た知見を自身の言葉で説明できるように知識拡充を行っていきたいと思いました。

最後までお読みいただきありがとうございました！！

PS：
次回の勉強回は2025.03.20（木）に開催されるようです！
初心者によるメモ（アルゴ式「九九の一覧」）

アルゴ式で間違えたところのメモ
## 問題
アルゴ式ロジック実装初級

https://algo-method.com/tasks/f6c9d310f48b1cbc

## 考察
二重ループを用いて数字は出力する。文字列にするにはf文字列を使うと便利。jの添え字に注意。

## ACコード
```py
for i in range(1,10):
    s = ""
    for j in range(1,10):
        print(f"{i} * {j} = {i * j}")
```
読書記録『独習Git』

## 概要
会社の人に勧めていただき、『独習Git』（リック・ウマリ 著 吉川 邦夫 翻訳、翔泳社、2016）を読んだので、その記録。

https://www.shoeisha.co.jp/book/detail/9784798144610

## こんな人におすすめ (私)
- Gitのpullとかpushはできるけど、細かい操作や仕組みがよくわかっておらずいつも不安
- 必要なコマンドをその場で調べて使うが、全体像がよくわかっていない
- サルでもわかる、みたいな簡単に解説してくれるサイトを見てもピンとこない
- コマンドラインが苦手

## ここがよかった
- Gitはもちろん、それ以外のコマンドについても丁寧な解説がある
- 何回か同じコマンドを繰り返すので、コマンドに慣れることができる
- フォルダ復元用のスクリプトが準備されており、途中で間違えても最初からやり直しが可能

## 今更ながらわかってよかったこと (git関連)
- gitのスイッチ
    - １文字のスイッチにはダッシュ１個
        - 例：-p
    - 略さないスイッチにはダッシュ２個
        - 例：--version
- `origin` はリモートのこと
    - デフォルト名なので変更も可能。リモートを複数作ることも可能。
- git コマンドのエイリアスを作れる
    - `git config --global alias.エイリアス名 "コマンド中身"`
- ブランチの派生を視覚的に表す
    - `git log --oneline --decorate --simplify-by-decoration --all --graph`
- その単語を含むファイル名の出力
    - `git grep 単語`
- コマンドのタイポを0.1秒後に自動補正する設定
    - `git config --global help.autocorrect 1`
- マージやrebaseのキャンセル
    - コミットメッセージの編集画面でコミットメッセージを全て消す
        -  `%d`
-  rebase前の状態に戻す（何回もやっているけどいつも忘れるのでメモ）
    -  git reflogでrebaseを開始する直前のコミットの別名（HEAD@{n}) を見つけ出す
    -  `git reset --hard HEAD@{n}`
        -  ステージングエリアと作業ディレクトリ両方リセットされる
-  ブランチを作る時は、ファイルがコピーされているわけではなく、親コミットへのポインタを持っているだけ
-  rebaseはブランチの開始地点を派生元の今の最新のコミットにする（何回も聞いているけど今回ちゃんとイメージがついたような）


## 今更ながらわかってよかったこと (git以外のコマンド)
- `Ctrl + A` : 行の先頭に移動
- `Ctrl + E` : 行の末尾に移動
- `echo 'test' >> b` : ファイルbの末尾に'test'を追記（ファイルがない場合は新規作成される）（これも何回もやっているが）
- `history | grep 単語`：過去のコマンド検索


## 感想
コマンドやgitに少し慣れ、恐怖心が減った気がする。使っているうちに覚えるだろうとその場しのぎでコマンドを調べていたが、tutorialをちゃんとやる方が近道なのかもしれない。
【詳細画面】textareaを入力不可 & フォーカス時の青い線を消す方法

# 方法
ポイント
①readonly：ユーザーは編集できない
②focus:ring-0 focus:border-gray-300：フォーカス時に青い線を消す
```
<textarea 
⭐️readonly 
class="w-full rounded border border-gray-300 h-32 text-base outline-none text-gray-700 py-1 px-3 resize-none leading-6 transition-colors duration-200 ease-in-out 
⭐️focus:ring-0 focus:border-gray-300">
{{ $item->comment }}
</textarea>
```
Windows11(23H2)へのIIS(Internet Information Services)インストール手順

# 概要
個人開発でWindows11(23H2)上へFTPサーバーやWebサーバーを立てるために調べたIIS(Internet Information Services)をインストールする手順を解説します。
※実際のサーバーの立て方は「**参考資料**」を確認してください。

# 前提条件
・Windows11(23H2)
 
# IISのインストール
・スタートメニューを開く
![win11_IISインストール_1-1_スタートメニュー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677151/11a86713-3c77-8f59-eaa2-95e946e1c271.png)
・「システム」タブを選択し、「オプション機能」を押下
![win11_IISインストール_1-2_設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677151/140f3b1a-2f8c-0f48-6df6-bb36bd154c9f.png)
・「関連設定」カテゴリから「Windowsのその他の機能」を押下
![win11_IISインストール_1-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677151/573426b3-0346-4834-114e-1a558c2cb854.png)
・「Windowsの機能」から「インターネット インフォーメーション サービス」にチェックをつける
![win11_IISインストール_1-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677151/be0cf67d-7c49-c44b-9981-e3ab4935e5f0.png)
・「インターネット インフォーメーション サービス」の左の「＋」ボタンを押下しメニューを展開
![win11_IISインストール_1-4-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677151/ba39742e-5ec7-5bcd-be17-4e494eeb3f5a.png)
・「FTPサーバー」にチェックをつける
・チェックが完了したらWindows下の「OK」を押下する
![win11_IISインストール_1-4-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677151/53b201ff-1605-7a6c-62ca-06c90a5940c8.png)
・変更が適用されるのでしばらく待つ
![win11_IISインストール_1-5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677151/b5f45a91-012f-a269-804b-02cd70b69b8a.png)
・適用が完了したら再度スタートメニューを開く
![win11_IIS設定_1-0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677151/e1789999-3dd9-d112-b9e5-54f32485ddcc.png)
・検索タブに「IIS」と入力する
・「インターネット インフォーメーション サービス（IIS）マネージャー」を押下する
![win11_IIS設定_1-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677151/cdc9cc18-cf21-b213-2c6d-bf9b7a20fff7.png)
・「インターネット インフォーメーション サービス（IIS）マネージャー」が開き、インストール完了
![win11_IIS設定_1-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677151/afc5c3ee-4acb-2411-5e50-2899359e1861.png)

# まとめ
OSのアップデートなどでたびたびアプリケーションの配置などが変わるので調査しました。

# 参考資料
・[Windows10でIISを構築する基本手順（IIS）](https://qiita.com/MURAMASA2470/items/819df8e1069737deb281)
・[Windows IISでFTPサーバーを立てる](https://qiita.com/MURAMASA2470/items/819df8e1069737deb281)
Pythonで効率的なモジュラー指数法を実装してみた

# はじめに
こんにちは！今回は分割統治法(Divide and Conquer)と動的計画法(Dynamic Programming)を組み合わせて、効率的にべき乗を計算しうるモジュラー指数法(Modular Exponentiation)をPythonで実装する方法を紹介します。
モジュラー指数法は次の形の計算を効率よく行うアルゴリズムです。
base^exp % mod (baseのexp乗をmodで割った余り)
### この記事で紹介する内容
- 分割統治法を利用したアルゴリズムの概要
- 動的計画法を活用した効率的な計算
- Pythonのコード実装とっその解説
- 実行例
# モジュラー指数法とは？
べき乗の計算は指数が大きくなると非常に計算コストがかかります。例えば、673^283 % 713のような計算を直接行うと、桁数が膨大となりメモリや処理速度が大きく影響を受けます。これを効率よく処理するのがモジュラー指数法です。分割統治法を用いることで計算量を減らし、指数計算の負担を軽減します。
# 実装コード
以下がPythonで実装したコードです。
```py:Mod.py
def mod_exp(base, exp, mod):
    """効率的なモジュラー指数法を用いて base^exp % mod を計算する関数"""
    result = 1
    while exp > 0:
        if exp % 2 == 1:
            result = (result * base) % mod
        base = (base * base) % mod
        exp //= 2
    return result

# ユーザ入力
base = int(input("基数（base）を入力してください: "))
exp = int(input("指数（exp）を入力してください: "))
mod = int(input("モジュロ（mod）を入力してください: "))

# それぞれの値を計算
P8 = mod_exp(base, 2, mod)
P7 = (P8 * P8) % mod
P6 = (P7 * P7) % mod
P5 = (base * P6 * P6) % mod
P4 = (base * P5 * P5) % mod
P3 = (P4 * P4) % mod
P2 = (base * P3 * P3) % mod
P1 = (base * P2 * P2) % mod

# 結果の出力
print("(1) P8 の値:", P8)
print("(2) P7 の値:", P7)
print("(3) P6 の値:", P6)
print("(4) P5 の値:", P5)
print("(5) P4 の値:", P4)
print("(6) P3 の値:", P3)
print("(7) P2 の値:", P2)
print("(8) P1 の値:", P1)
```
# アルゴリズム解説
### モジュラー指数法(分割統治法)
このプログラムでは指数の計算を指数を半分に分割しながら行っています。例えば、base^8を計算する際にbase^4を2回掛ける形にすれば、計算量が大幅に減ります。また、偶数・奇数の処理に応じて計算結果を更新しながら最終的な答えを得ます。
### 動的計画法(Dynamic Programming)
同じ計算を繰り返さないように、既に計算した値を再利用しています。P8の計算結果を使ってP7を計算するなど、動的計画法の考え方を活用することで無駄な処理を省いています。
# 実行例
次のような入力をした場合の実行結果を示します。
```
基数（base）を入力してください: 673
指数（exp）を入力してください: 283
モジュロ（mod）を入力してください: 713
(1) P8 の値: 174
(2) P7 の値: 330
(3) P6 の値: 524
(4) P5 の値: 12
(5) P4 の値: 657
(6) P3 の値: 284
(7) P2 の値: 85
(8) P1 の値: 478
```
# まとめ
モジュラー指数法を使えば、指数が大きな計算でも高速に結果を求めることができます。今回の実装では動的計画法を組み合わせることで、さらに効率を向上させました。最後まで読んでくださり、ありがとうございました。もし改善点や質問があれば、ぜひコメントしてください！
Excel VBA バーコードリーダーの情報をエクセルに書き出す

### はじめに
バーコードリーダーの情報をエクセルシートへ書き出しを行う

### プロシジャーの説明
任意のバーコードをスキャンして、A列の1行目から順に読み込みます

#### サンプル１ 
``` VB
Sub ReadBarcode()
    Dim LastRow As Long
    Dim BarcodeValue As String
    
    ' A列の最終行を取得
    LastRow = Cells(Rows.Count, 1).End(xlUp).Row
    
    ' バーコード値を取得するための入力ボックスを表示
    BarcodeValue = InputBox("バーコードをスキャンしてください:", "バーコードスキャン")
    
    ' キャンセルが押された場合は処理を終了
    If BarcodeValue = "" Then Exit Sub
    
    ' A列の最終行の次のセルにバーコード値を入力
    Cells(LastRow + 1, 1).Value = BarcodeValue
End Sub
```
え？本買ってるの？？もっと良い方法あります。

## はじめに
日々の業務で新しい技術をキャッチアップするのは大変ですよね。特にライブラリやフレームワークの学習では、公式ドキュメントが丁寧でないこともあり、どこから手をつければいいか悩むことも多いと思います。

先日の会社の定例で紹介したTipsが好評だったので、その内容を共有します。


株式会社シンシアでは、実務未経験のエンジニアの方や学生エンジニアインターンを採用し一緒に働いています。
※ シンシアにおける働き方の様子はこちら
https://www.wantedly.com/companies/xincere-inc/stories

本記事では、「本を読むのが無駄」という主張ではなく、「本以外にも便利な学習手段がある」という視点でお話しします。

## 本の必要性
各分野には「名著」と呼ばれる本が存在し、それらは基礎をしっかりと学ぶのに適しています。

https://qiita.com/Sicut_study/items/0b27dca18af96c80bec8


しかし、ライブラリやフレームワークの学習ではどうでしょうか？

公式ドキュメントがしっかり整備されている場合もありますが、すべてのドキュメントが初心者に優しいわけではありません。とはいえ、「ドキュメントが分かりにくいからキャッチアップしない」という選択肢はありません。

そこで、本の代替手段として **ChatGPT を活用する方法** を紹介します。

## ドキュメントをChatGPTに読ませ、ハンズオンを作らせる
ライブラリやフレームワークの学習で、公式ドキュメントを読むのが苦痛に感じることはありませんか？ そんなときは、**ChatGPT にドキュメントを要約させ、簡単なハンズオンを作成させる** ことで、より実践的に学ぶことができます。

#### **具体的な方法**
1. **ドキュメントのURLをChatGPTに要約させる**
   ```
   URLのドキュメントを要約してください: [ドキュメントのURL]
   
   //必要であればGithubのREADMEのURL
   GithubのREADMEを要約してください : [GithubのURL]
   ```
![スクリーンショット 2025-02-11 19.52.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3999339/faab5c5d-0d74-0113-86a4-16eea57bed57.png)
2. **ハンズオンを作成させる**
   ```
   このライブラリの基本的な使い方を学ぶために、初心者向けのハンズオンを作成してください。
   - 必要なセットアップ手順
   - 簡単なサンプルコード
   - よくあるエラーとその対処法
   ```
![スクリーンショット 2025-02-11 19.56.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3999339/70cbaa44-a4ac-0493-1c57-7de17082cfe4.png)

3. **実際に手を動かして学ぶ**
   - ChatGPT が作成したハンズオンを試しながら学習を進めることで、単にドキュメントを読むよりも理解が深まります。
   - 必要に応じて、ChatGPTに質問するのも有効です。

#### 難易度調整も可能
初心者向けとするとかなり簡単なハンズオンを作成できます。簡単すぎると感じたら、鬼ムズにすることもできるので、お好みに合わせて調整しましょう。
![スクリーンショット 2025-02-11 20.03.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3999339/876ed3fd-a4ac-e456-44dd-41c089268bd7.png)
## まとめ
ライブラリやフレームワークの学習では、ChatGPTを活用したハンズオン作成により、効率よくキャッチアップできます。
ただ単にChatGPTが生成するハンズオンは、どこを参照しているのか不明瞭になりがちですが、こちらで適切な読み物を用意することで、明確な流れのハンズオンを作成できます。

また、ChatGPTに資料を読ませる方法は他にも活用の幅がありそうです。これからの時代、AIの使いこなしが重要なスキルになりそうですね。
Pandasの利用時に詰まった箇所

## はじめに
Pythonにおける、Pandasライブラリを利用したデータ変換を行う際に  
詰まった箇所を戒めも兼ねてまとめました。

## Seriesにおける値の結合
Seriesの要素に対して値を結合しようとした際ですが、  
対象Seriesの値がNaNの箇所は結合されません。  
有効な文字列を持っている行に対してのみ結合が行われます。

```py
# 空のdfAに対して、一部の箇所の値がNaNであるdfBを代入
dfA["列名"] = dfB["列名"]

# 値がNaNの箇所は、要素どうしのの結合が行われない
dfA["列名"] = dfA["列名"] + dfC["列名"] 
```

### 対処法
「.fillna("")」を利用し、NaNを空文字にする
```py
# dfBに含まれているNaNを空文字に変換する
dfA["列名"] = dfB["列名"].fillna("")

# NaNが空文字に置き換えられているため、問題なく結合が行われる
dfA["列名"] = dfA["列名"] + dfC["列名"] 
```

## replace利用時の挙動の違い
### .replace
行に入っている値の中身を全部変換する場合は、.strは不要
### .str.replace
文字列操作(例えば文字列の一部置換など)の場合は、.strが必要

## 意図せず行の値がタプルになる
### 症状
データを入れる処理に続けて、  
10行分のデータを入れている最中に下記のエラーが発生した
```
valueerror length of values (1) does not match length of index (10)
```
### 原因
エラーが発生した処理の1つ前の処理のコードを見ると、  
以下のように不要なカンマがついていた。
```py
dfA["列名"] = (固定値 + dfB["列名"],)
```
Pythonの構文上、最後にカンマがついているため  
10行分のデータを持った1つのタプルとして判別されており    
1行分のデータしか入っていない状態になっていた。
  
また、VSCodeのフォーマッターで自動的に括弧がつくのも  
判別のしづらさに一役買い、原因箇所特定に時間を要してしまった。

### 対処法
不要なカンマを除去する
```py
dfA["列名"] = (固定値 + dfB["列名"])
```

## DataFrame値の文字列分割(.strつけ忘れ)
### 誤ったコード
下記のようにすると、dfB列における最初の3行を抽出してしまう。
```py
dfA["列名"] = dfB["列名"][:3]
```
### 正しいコード
「.str」をつけると、dfB列の各要素における最初の3文字を取得する
```py
dfA["列名"] = dfB["列名"].str[:3]
```

## 参考
- Pythonで要素が1個のタプルには末尾にカンマが必要
  - https://note.nkmk.me/python-tuple-single-empty/
Markdown記法とは

# マークダウンとは？
マークダウンとは、アメリカ合衆国、フィラデルフィア出身のライター・コラムニストであるジョン・グルーバー（John Gruber）によって、2004年に開発された「フォーマット」のこと。

「日本語マークダウンユーザー会」では、マークダウンの特徴を以下にまとめられている。
1. 手軽に文章構造を明示できること
1. 簡単で、覚えやすいこと
1. 読み書きに特別なアプリを必要としないこと
1. それでいて、対応アプリを使えば快適に読み書きできること

マークアップもある。

参考：[【マークダウン記法とは？】マークダウンの書き方を網羅的に解説](https://backlog.com/ja/blog/how-to-write-markdown/#%E3%81%9D%E3%82%82%E3%81%9D%E3%82%82%E3%80%8C%E3%83%9E%E3%83%BC%E3%82%AF%E3%83%80%E3%82%A6%E3%83%B3%E3%80%8D%E3%81%A8%E3%81%AF%EF%BC%9F)

書く際はこれを読む
[Markdown記法 チートシート](https://qiita.com/Qiita/items/c686397e4a0f4f11683d)