OmniAICreator/Qiita-1.07M huggingface dataset:
Flutterでglobalに使用できるcontextの作り方

# NavigatorKey
## 概要
`NavigatorKey`はグローバルなBuildContextを取得したい場合に使用する。
主にUIに依存しないダイアログなどを作成する場合に役に立つ。

## 実装
まずグローバルで`NavigatorKey`を宣言する。
```Dart
import 'package:flutter/material.dart';

final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
```

次に`MaterialApp`内で`NavigatorKey`をプロパティとして渡す。
大抵このウィジェットは`main.dart`内にある。
```Dart
class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: APP_THEME_DATA,
      navigatorKey: navigatorKey, //ここを追加
      home: const MyHomePage(),
    );
  }
}
```

これで`navigatorKey`を使用してBuildContextなしでcontextを取得できるようになった。
書き方は`navigatorKey.currentState!`である。
以下はその例。
BuildContext引数なしでcontextを取得することができている。
```Dart
showWarnDialog(){
  showDialog(
    context: navigatorKey.currentContext!,
    builder: (BuildContext context){
      return ... ;
    } 
  );
```
抽出の更新を今すぐ更新　ができない事例

Tableau cloud上のワークブックに対して
データソースをすぐに更新する「抽出を今すぐ実行」
機能ですが、サイトの設定によりこちらがオフになっている場合がごさいます。
（お客様環境のセキュリティの観点など）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3119468/ce1185c9-b545-45eb-9db8-baa04efc7736.png)

●代替案
「抽出の更新をスケジューリング」機能で5分刻みで一番近い未来の時間を設定
➡設定した時間になれば抽出の更新が実行される。

バッチ内でのコマンド👇
Extract and Encryption Methods - Tableau
※RefreshExtract

最後まで読んでいただきありがとうございました！
いいね！お願いいたします！
アクセストークンについて

●アクセストークンとは
Tableau ServerやTableau CloudへのAPIアクセスを認証するためのトークンです。
アクセストークンを使用することで、ユーザー名やパスワードを直接使わずに、
プログラムや自動化されたプロセスからTableauにアクセスできます。
これによりセキュアで効率的なAPI操作が可能になります。


●APIとは
Tableau ServerやTableau Cloudに対して、プログラムからアクセスして管理することが可能です。
例）
ユーザー管理
グループ管理
ワークブック管理
データソース管理
プロジェクト管理 など

●アクセストークンを使用するメリット
・セキュリティの向上
ユーザー名、パスワードを使用せずサインインとが可能なので、
セキュリティ面で安心
・簡便な認証
ユーザー名とパスワードを毎回入力する必要がない
・管理が簡単
セキュリティ上必要な場合に簡単に無効化したり、新しいものを生成が可能

●アクセストークンの作成方法
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3119468/5c8e2c9f-d1a4-4973-94ca-94ac42f9fd45.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3119468/0071b090-2cc9-4400-9116-d9fafce42130.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3119468/4bb022bb-3802-4bc8-a870-7474c0565367.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3119468/096c9fd3-db29-43b0-a33b-ce4d60b7088c.png)


●注意点1
・アクセストークンが消えた？！
➡tableau cloudのアップデートによりアクセストークンが消える事象がある？
　bat内で使用している場合、bat実行前にアクセストークンが存在しているか確認してください。
➡15 日間連続して使用されなかった場合　も消えます。
https://help.tableau.com/current/online/ja-jp/cloud_manager_personal_access_tokens.htm

●注意点2
発行者のサイトロールに紐づいている為、viewerライセンスの方が発行したアクセストークンでは実行できない
creatorライセンスの方が発行したアクセストークンでは実行できる等。

●注意点3
使用する環境によっては文字数制限、大文字、小文字、記号制限がある？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3119468/6a4851aa-8e8b-4b24-81cd-e30f8475c9ac.png)

①記号ありなしの差異（緑）
②環境によっての差異（赤）
③文字数による差異（青）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3119468/43ff64f6-6492-4975-b350-42188fd1d134.png)
※お客様情報を一部置換しております。

最後まで読んでいただきありがとうございました！
いいね！お願いいたします！
Firestoreのプロジェクト間移行を少しだけ楽にやってみた

:::note warn
以下は完全に自分用でメモ程度にまとめたものなので、詳細は公式ドキュメントまたは参考になった記事を参照されることをおすすめします。
:::

## 経緯
本来の手順としてはざっくり以下のようなフローだが、
```
(移行元)Firestore → (移行元)Cloud Storage → (移行先)Cloud Storage → (移行先)Firestore
```
Cloud Storageに対してサービスアカウントがプロジェクト間をクロスするような形で運用することが想定される。実際にやってみたところ、移行元のCloud Storageにて移行先のサービスアカウントに対する権限の付与や、gcloudでの設定の切り替えが煩雑になってしまい手間取ってしまった。ついでにどのロールが必要になるのか試行錯誤しながらやったため時間がかかってしまった。( "Storage **レガシー**読み取り" が必要ってわからないよ…)

以下のようなフローで実施したことにより、ちょっとだけ楽ができた＆自分にとってはわかりやすかったので備忘録として残しておきます。
```
(移行元)Firestore → (移行元)Cloud Storage → ローカルへダウンロード → (移行先)Cloud Storageへアップロード → (移行さｋ)Firestore
```

:::note
Firebase/GCPコンソール上でもある程度は操作できますが、Google Cloud SDK(CLI)で作業しています。
:::
## 1. 移行元プロジェクトでの手順

1. Cloud Storageにて、Firestoreのデータベースと同じリージョンでバケットを作成する

2. Google Cloud SDKで操作する際は、Firestoreで使用するサービスアカウントに次の権限が付与されるようにする

   * Storage オブジェクト 管理者
   * Storage レガシー バケット 読み取り

3. 権限を付与したサービスアカウントのキーをダウンロードする

   ``` powershell
   gcloud iam service-accounts keys create ~/path/to/key.json \
   --iam-account=<your-serviceaccount@iam.gserviceaccount.com>
   ```

4. サービスアカウントを認証する

   ```powershell
   gcloud auth activate-service-account \
   <your-serviceaccount@iam.gserviceaccount.com> \
   --key-file=~/paht/to/key.json
   ```

5. 認証したサービスアカウントをデフォルトプロジェクト・アカウントに設定

   ```powershell
   gcloud config set project <src-project-id>
   gcloud config set account <your-serviceaccount@iam.gserviceaccount.com>
   ```

6. Firestore → Cloud Storage にエクスポート

   ```powershell
   gcloud firestore export `
   <エクスポート先バケット>/<エクスポートプレフィックス> `
   --project=<src-project-id>
   ```

## 2. ローカルでの手順

1. Cloud Storageからローカルへ再帰的にダウンロード

   ```powershell
   gsutil -m cp -r `
   <エクスポート先バケット>/<エクスポートプレフィックス> `
   <ローカル保存先>
   ```

## 3. 移行先プロジェクトでの作業

1. 移行先プロジェクト・サービスアカウントに切り替える

   ```powershell
   gcloud config set project <dest-project-id>
   gcloud config set account <your-serviceaccount@iam.gserviceaccount.com>
   ```

2. 移行先プロジェクトでのサービスアカウントにCloud Storage, Firestoreの権限を付与する

   * Storage オブジェクト 管理者

3. ローカルからCloud Storageへ再帰的アップロード

   ```powershell
   gsutil -m cp -r `
   <ローカル保存先パス>\<エクスポートプレフィックス> `
   <アップロード先バケット>
   ```

4. Firestoreでデータベース名 `(default)` を作成しておく

5. Cloud Storage から Firestore へインポート

   ```powershell
   gcloud firestore import `
   <アップロード先バケット>/<エクスポートプレフィックス> `
   --project=<dest-project-id>
   ```

:::note warn
なお、Firestoreへはデータベース名が `(default)` でインポートされるが、任意のデータベース名を指定してインポートできるかは未確認
:::

## 参考
https://qiita.com/ricemountainer/items/b8ae801c0a35e610df92


https://firebase.google.com/docs/firestore/manage-data/move-data?hl=ja&_gl=1*1rrrwmf*_up*MQ..*_ga*MTYyNjMxNDYyNS4xNzQ3OTAyMzYw*_ga_CW55HF8NVT*czE3NDc5MDIzNTkkbzEkZzAkdDE3NDc5MDIzNTkkajAkbDAkaDAkZHlUc2RTaHpIcDNiWXAxMGFVaUJ6bW8tNUJvZ2k4QXRqVnc.
📘 Vol.1〜7 総まとめ：画面駆動開発で学ぶ Struts2実践プロジェクトの軌跡

> ✅ 本記事は、Vol.1〜7.4 までの内容を網羅的に振り返り、「次に進むための全体像」を掴むためのまとめです。

---

## 🧭 Vol.1〜7 概要一覧

| 回 | タイトル | 主な内容 |
|----|----------|-----------|
| Vol.1 | [プログラミングとの再会 – 「画面ありき」で変わった学び方](https://qiita.com/juehara-crypto/items/2fcc53d765dcc25a4fa3) | プログラミング再入門と、**画面駆動の学習法**というユニークなアプローチの紹介。最初に「画面」から考えることでモチベーションを継続。 |
| Vol.2 | [画面駆動設計に基づく設計書の具体例：画面フローからUI設計・処理定義まで](https://qiita.com/juehara-crypto/items/c1fd34b3031b13160f27) | 実際に描いた**画面遷移図・UI設計・処理定義書**を公開し、画面中心の設計手法を解説。 |
| Vol.3 | [詳細設計編：ER図で見るデータ構造と実装の土台](https://qiita.com/juehara-crypto/items/6e6431954dc99ea59054) | 実装前提で設計された **ER図（Entity Relationship 図）** をもとに、データ構造と整合性を設計。 |
| Vol.4 | [Struts2とMavenの基礎と設定ファイルの役割](https://qiita.com/juehara-crypto/items/e37fa1879ae996bee73e) | Struts2の構成とMavenでの管理、`web.xml` や `pom.xml` の役割を丁寧に解説。 |
| Vol.5 | [環境構築編：掲示板アプリケーションの実行準備](https://qiita.com/juehara-crypto/items/7010ae45d35174d3a3a6) | TomcatとEclipseでの動作環境構築。 |
| Vol.6 | [BaseActionクラスの詳細解説【Struts2の要】](https://qiita.com/juehara-crypto/items/a5f244a5f58597f33d06) | すべてのアクションに共通する基底クラス **BaseAction** を定義し、ログ出力や共通処理を集約。 |
| Vol.6.1 | [BaseAction の活用例【共通基底クラスでセッション管理を簡素化】](https://qiita.com/juehara-crypto/items/f4efded5b26e39e49928) | BaseAction を継承する具体的なアクション例を紹介し、セッションやログ処理の統合例を実践。 |
| Vol.7 | [Struts2 における MVC モデルの全体像](https://qiita.com/juehara-crypto/items/761c0b13ed1a5f896bba) | Model-View-Controller の各要素が Struts2 でどう分担されるかを体系的に解説。 |
| Vol.7.1 | [Struts2 における Model（モデル）について](https://qiita.com/juehara-crypto/items/14f7f154caf29447ae93) | JavaBeansベースのModelクラス（User, Thread, Post など）設計とその役割を明確化。 |
| Vol.7.2 | [Struts2 における Controller（コントローラ）の責務](https://qiita.com/juehara-crypto/items/06b4f9296a296db8f4ba) | Actionクラスを軸に、入力処理・分岐処理・画面遷移の中核を担うControllerの実装指針を提示。 |
| Vol.7.3 | [Struts2 における struts.xml の書き方と役割](https://qiita.com/juehara-crypto/items/54dc2e0a4d56845a1a61) | URLマッピング、結果遷移、アクション定義の方法を丁寧に記述。初心者の詰まりやすいポイントを回避。 |
| Vol.7.4 | [struts.xmlの高度な設定と実践活用（Struts2）](https://qiita.com/juehara-crypto/items/bf03adbd840c8f4e2044) | namespaceの活用や画面単位での分離設計、開発時の保守性向上テクニックを紹介。 |

---

## 🔑 本シリーズの3大特徴（Vol.1〜7時点）

### 1. **画面ファースト設計**
- 「何を作るか」ではなく「どう見せるか」から始める、初心者に優しいアプローチ。
- 実務でも「UIワイヤーフレーム起点」での設計に応用可能。

### 2. **共通基底クラスの導入**
- `BaseAction` によるロギング・セッション管理の一元化で、全体の保守性と可読性が向上。

### 3. **MVCをStruts2流に徹底理解**
- JavaEEにおける典型的なMVC構造を、Model（Bean）・View（JSP）・Controller（Action）に明確分離。
- `struts.xml` の構成まで含めて「見える化」された構成を構築。

---

## 📘 まとめと次回予告

Vol.1〜7 で、**Struts2の設計・構築・設計指針までの基礎**を網羅しました。  
この土台をもとに、Vol.8 以降では以下のような実装フェーズに突入します。

### 次に読むべき記事
- 📘 [Vol.8.0：Struts2 タグの活用と画面構築の進化](https://qiita.com/juehara-crypto/items/xxxx) ←（準備中または差し替え）

---

📌 **この記事の役割：**
- Vol.0〜7.4 を通読した方の「理解の定着」。
- Vol.8〜への「導線ナビゲーション」。
- シリーズ全体の「整理と俯瞰」による復習。

---
競プロ日記#25/05/22

# 競技プログラミングの鉄則
[A11 - Binary Search 1](http://atcoder.jp/contests/tessoku-book/tasks/tessoku_book_k)
- 単純な二分探索
- 読み物としては書籍を一周していたのもあってこのレベルであれば問題なくACできた。

[A16 - Dungeon 1](https://atcoder.jp/contests/tessoku-book/tasks/tessoku_book_p)
- 簡単な動的計画法の問題
- これも同じく書籍の読破はしていたのとアルゴ式でも動的計画法は触れていたのでACできた。

[A26 - Prime Check](https://atcoder.jp/contests/tessoku-book/tasks/tessoku_book_z)
- 素数判定問題
- この前アルゴ式の整数論的アルゴリズムでやった「ミラーラビンの素数判定」を活用して回答した
- おそらく問題の意図としては素数判定のアルゴリズムそのものを実装してくれってことだとは思うが、そもそもアルゴ式で散々触れたので流用した

[A36 - Travel](https://atcoder.jp/contests/tessoku-book/tasks/tessoku_book_aj)
- 考察の章はネタバレになるのでほぼ見ていなかったがそれでも一発目でそんなに難しくなかったからかACできた。
- 1度条件のところで```K >= N * 2 -2```とするところを```K > N * 2 -2```としてしまいWAしてしまった
LinuxでのUSBメモリフォーマット

# LinuxでのUSBメモリフォーマット

## １．マウントポイント・デバイスファイル名の確認
```bash
lsblk -f
```

## ２．パーティショニング
```bash
gdisk /dev/{デバイスファイル名}
```
USBメモリをパーティショニングする際のHex codeは0700（Microsoft basic data）となる。


```bash
Command (? for help): o（新しいGPTパーティションテーブル作成）
This option deletes all partitions and creates a new protective MBR.
Proceed? (Y/N): y

Command (? for help): n（パーティションテーブルに新しいパーティション追加）
Partition number (1-128, default 1):  （デフォルト値）
First sector (34-500118158, default = 2048) or {+-}size{KMGTP}: （デフォルト値）
Last sector (2048-500118158, default = 15826910) or {+-}size{KMGTP}: （デフォルト値）
Current type is 8300 (Linux filesystem)
Hex code or GUID (L to show codes, Enter = 8300): 0700（Microsoft basic dataのHex codeを入力）
Changed type of partition to 'Microsoft basic data'

Command (? for help): w（ディスクにパーティションテーブル書込）

Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
PARTITIONS!!

Do you want to proceed? (Y/N): y
OK; writing new GUID partition table (GPT) to /dev/sdd.
The operation has completed successfully.
```

## ３．フォーマット
mkfs.vfat を使う。
```text:コマンドオプション
-v：進捗を表示
-c：不良ブロックの精査を行う
-F： FATサイズを指定。基本32
-n：ボリューム名（ラベル）を指定
```

```bash
mkfs.vfat -v -c -F 32 -n USBDEV /dev/sdd1 
```
【WebGL】ファイル操作の同期ネイティブコード

# Unityドキュメントより
> ### 問題: Application.persistentDataPath に保存したファイルが永続化されない
> Unity WebGL は、セッション間で永続化させる必要のあるすべてのファイル (PlayerPrefs や persistentDataPath に保存されるファイルなど) をブラウザー IndexedDB に保存します。これは非同期 API なので、いつ終了するか分かりません。
>
> 以下のコードを呼び出して、メモリから IndexedDB ファイルシステムへの、持続中のファイルシステムの書き込み操作をすべてフラッシュするようにします。
> 
> ```javascript
> FS.syncfs(false, function (err) {
>  if (err) {
>    console.log("Error: syncfs failed!"); 
>  }
> });
> ```
https://docs.unity3d.com/ja/2022.3/Manual/webgl-debugging.html

上記の記載はUnity2022.3までのリファレンスだとあるのに（若干少しずつ記述が更新されていたが）、Unity6000以降は同じページが見つからない。

ただ、Unity6000.2だと

> <table><colgroup><col style="text-align:left;"><col style="text-align:left;"></colgroup><thead><tr><th style="text-align:left;">Property</th><th style="text-align:left;">Use</th></tr></thead><tbody><tr><td style="text-align:left;"><code>autoSyncPersistentDataPath: true</code></td><td style="text-align:left;">If set to true, all file writes inside the Unity <code>Application.persistentDataPath</code> directory automatically persist so that the contents are remembered when the user revisits the website the next time. If unset (or set to false), you must manually sync file modifications inside the <code>Application.persistentDataPath</code> directory by calling the <code>JS_FileSystem_Sync()</code> JavaScript function.</td></tr></tbody></table>

https://docs.unity3d.com/6000.2/Documentation/Manual/web-templates-build-configuration.html

という記載があり、「わざわざネイティブコードで呼ばなくても自動的に同期してくれる設定もできたけど、使用しないのであれば依然としてこれまでと同じく `JS_FileSystem_Sync()` 呼んでくれてもいいよ」（意訳）と書いてあるように思う。

ということで、次節で書き残すコードは今後も無価値無意味ではなさそう。
単純に、自分の実装では使い道がなくなっただけなので、ここで供養（≒アウトプット）しておく。

# 同期コード
デリゲート地獄だけどやむなし。

```javascript:idbfs.jslib
mergeInto(LibraryManager.library, {

    SyncFS: function (callback) {

        FS.syncfs(false, function (err) {
            if (err){
                var buffer = stringToNewUTF8(err.message);
                {{{ makeDynCall('vii', 'callback') }}} (false, buffer);
                _free(buffer);
            } else {
                {{{ makeDynCall('vii', 'callback') }}} (true, null);
            }
        });
    },
});
```

```cs: NativePluginsBridge.cs
using System;
using System.Runtime.InteropServices;
using AOT;
using UnityEngine;

namespace DefaultNameSpace
{
    public static class NativePluginBridge
    {
        public static event Action OnSyncFSCompleted;

        [DllImport("__Internal")]
        private static extern void SyncFS(Action<bool, string> callback);

        [MonoPInvokeCallback(typeof(Action<bool, string>))]
        private static void SyncCall(bool success, string message)
        {
            if (success)
            {
                OnSyncFSCompleted?.Invoke();
            }
            else
            {
                Debug.LogError("SyncFS failed: " + message);
            }
        }
        
        public static void SyncFS() => SyncFS(SyncCall);
    }
}
```

# 追伸
いつの間にやら、`dynCall()` は非推奨になったらしいので、注意。

https://docs.unity3d.com/6000.0/Documentation/Manual/web-interacting-browser-deprecated.html
構造力学カリキュラム(日記)


⸻

構造力学 カリキュラムまとめ（第1章〜第10章）

第1章：構造力学の概要

1.1 構造力学とは
	•	内容：建物や橋などの構造物に作用する力と、それに伴う変形・応力を扱う工学の基礎。
	•	目標：構造力学の位置づけと目的（安全・経済・機能）を理解する。

1.2 力とモーメント
	•	力の定義、単位、モーメント（力の回転効果）の計算

1.3 つりあい条件
	•	静力学の基本：力の合計・モーメントの合計がゼロの条件

⸻

第2章：構造物の分類と支持条件

2.1 構造物の分類
	•	内容：ラーメン構造、トラス、アーチ、ケーブル、シェルなどの構造形式

2.2 支持条件と反力
	•	固定、ピン、ローラーなどの支持条件とそれに対応する反力の種類を理解

⸻

第3章：静定構造物の反力解析

3.1 静定構造物とは
	•	定義：釣り合い条件のみで解が求まる構造物（不静定でない）

3.2 支持反力の求め方
	•	静力学の3つの式（ΣFx=0, ΣFy=0, ΣM=0）を用いた解析

⸻

第4章：力のつりあいと分解

4.1 力の合成と分解
	•	ベクトルとしての力の扱い。直交成分への分解、斜面での力の取り扱い

4.2 モーメントの計算
	•	任意の点に対するモーメント、合力の位置など

⸻

第5章：構造物への荷重と応答

5.1 荷重の種類
	•	集中荷重、分布荷重、モーメント荷重、動荷重など

5.2 影響線
	•	移動荷重による応答の変化を表現するための影響線図



第6章：断面力の算定

6.1 断面力とは
	•	目的：部材内部に生じる力（軸力・せん断力・曲げモーメント）を理解
	•	内容：構造部材に外力が作用すると、その内部に生じる応力の源である「断面力」が発生する。

6.2 断面力の算定
	•	学習目標：
	•	モーメント図、せん断力図の描き方を理解
	•	外力の釣り合いから断面力を求める技術を習得

⸻

第7章：静定トラス構造物

7.1 トラス構造物とは
	•	内容：直線部材が節点で接続され、軸方向力のみで構成される構造

7.2 軸力算定方法

7.2.1 はじめに
	•	導入：トラスの力学的特徴と簡単な設計原理

7.2.2 解法A：節点つりあい法
	•	各節点での力の釣り合いから連立方程式を立て、軸力を求める手法

7.2.3 解法B：リッターの切断法
	•	トラスを切断し、全体の釣り合いから一部の部材の力を求める

⸻

第8章：断面の応力度および性質

8.1 応力度と断面力の関係（感覚的理解）
	•	内容：部材の内部応力（応力度）と外力（断面力）の関係を直感的に学ぶ

8.2 断面の性質
	•	学習内容：
	•	断面2次モーメント、断面係数、重心などの算定
	•	構造部材の耐力・剛性設計に必要な基礎知識

8.3 応力度

8.3.1 応力度の種類
	•	垂直応力・せん断応力・主応力・最大せん断応力

8.3.2 垂直応力度
	•	引張・圧縮における応力度の算出法

8.3.3 せん断応力度
	•	はり内部でのせん断応力の分布

⸻

第9章：梁のたわみ

9.1 はじめに
	•	内容：たわみの基本概念、影響要因

9.1.1〜9.1.3
	•	たわみに影響する因子：
	•	梁の長さ、断面形状、材料特性（ヤング係数）

9.2 材料の剛さ（ヤング係数）
	•	応力とひずみの関係、弾性係数の役割

9.2.1 その他の材料特性
	•	ポアソン比・塑性係数など

9.3 部材の剛性

9.3.1 軸力剛性：EA

9.3.2 曲げ剛性：EI

9.4 梁のたわみの算定方法
	•	モールの定理（力学的エネルギー法）
	•	微分・積分法（2階微分方程式で求解）

9.5 梁のたわみ公式集
	•	集中荷重・分布荷重を受ける単純梁・固定梁などのたわみ公式

⸻

第10章：長柱の座屈

10.1 座屈とは
	•	圧縮軸力を受けた部材が突然横方向に変形する現象

10.2 座屈の基本公式
	•	オイラーの座屈公式：P_cr = π²EI / (KL)²

10.3 弾性座屈耐力の算定
	•	支持条件・部材長・断面形状の影響を加味した算定方法

⸻

学習の全体目標
	•	応力と変形の関係を理解し、安全かつ効率的な構造設計の基礎を習得
	•	解析手法（釣り合い法、エネルギー法、微積分）を活用し、部材の設計や評価ができる

⸻
📗 Vol.8.11：タグの出力をスタイリッシュに！〜 UIの統一＆見た目の最適化Tips 〜

🔗 本章は「Vol.8.9〜：Struts2 タグライブラリ応用編（実務／初級応用）」シリーズです。

---

## 🎯 本記事の目的

Struts2 の `<s:form>` や `<s:textfield>` などのタグは便利ですが、**出力されるHTMLが地味／クセがある**ため、CSSフレームワーク（特にBootstrap）と連携させたい時に苦戦しがちです。

本記事では、以下の悩みを解決します：

- Struts2のフォームを**Bootstrap風に美しく整える**
- タグの出力構造を理解し、**CSSを自在に適用**する
- **エラーメッセージの表示**をスタイリッシュにする

---

## 1. Struts2 タグの出力HTML構造を理解する

### ✅ 例：`<s:textfield>` の出力

```jsp
<s:form action="login">
  <s:textfield name="username" label="ユーザー名"/>
</s:form>
```

出力されるHTML（簡略化）：
```html
<form action="login.action" method="post">
  <label for="username">ユーザー名</label>
  <input type="text" name="username" id="username" value="" />
</form>
```

- label属性 → <label>要素に変換

- name属性 → <input>要素の name/id に反映

---

### 2. 出力HTMLをCSSフレームワークで装飾する
### ✅ Bootstrap のクラスを適用するには？
```jsp
<s:textfield name="username" label="ユーザー名" cssClass="form-control"/>
```

→ 出力HTML：
```html
<input type="text" class="form-control" name="username" id="username" />
```

### ✅ `<s:form>`にクラス追加
```jsp
<s:form action="login" cssClass="form-horizontal">
```

---

### 3. エラーメッセージを見た目よく表示する

✅ `<s:fielderror>` の出力

```jsp
<s:fielderror/>
```

エラー時の出力例：
```jsp
<ul class="errorMessage">
  <li>ユーザー名は必須です。</li>
</ul>
```

### ✅ Bootstrap風に調整するには？
```css
.errorMessage {
  color: #dc3545;
  font-size: 0.9em;
  list-style: none;
  padding-left: 0;
}
```

→ text-dangerクラスに統一してもOK：

```jsp
<ul class="text-danger">
  <li>エラー内容</li>
</ul>
```

---

### 4. 実務Tips：よくあるUI調整パターン
### ✅ 入力項目を横並びにしたい！

```html
<div class="row mb-3">
  <label class="col-sm-3 col-form-label">ユーザー名</label>
  <div class="col-sm-9">
    <s:textfield name="username" cssClass="form-control"/>
  </div>
</div>
```
### ✅ 必須入力の「※」をラベルに追加
```jsp
<s:textfield name="username" label="ユーザー名 ※" required="true" cssClass="form-control"/>
```

### ✅ 成功メッセージ・警告メッセージの表示
```jsp
<div class="alert alert-success">登録が完了しました！</div>
<div class="alert alert-warning">入力内容を確認してください。</div>
```

### 5. まとめ＆次回予告
- Struts2のタグ出力構造を把握することで、CSS適用がスムーズに！

- Bootstrap等との連携には cssClass 属性が鍵！

---

### 📘 [次回予告：Vol.8.12 共通レイアウトと include の活用法](https://qiita.com/juehara-crypto/items/bbe57cc81a3834704c4c)
共通のヘッダー・フッター・メッセージ領域を includeで部品化し、
「見た目・構造の統一感」を手に入れましょう！

---

🔖 関連記事リンク
- [Vol.8.10：JSP カスタムタグの自作入門](https://qiita.com/juehara-crypto/items/10f85829a2e56e889cb3)

- [📘 Vol.8.0〜8.20 総まとめ & 実務逆引きリファレンス](https://qiita.com/juehara-crypto/items/60fde06e887bc420520d)
Power Automateでoutlookメールのカテゴリ取得メモ


こんな感じでカテゴリ（ラベル）設定中のメールに対して、"じゃがいも"カテゴリや"美術館"カテゴリなど任意のカテゴリのメールを取得します。

> ![CleanShot 2025-05-23 at 00.27.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/ca668f57-9a6f-4e2e-855b-331cc648d602.png)

一旦の完成イメージのフロー

> ![CleanShot 2025-05-23 at 00.52.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/92cc1838-59e8-4777-8985-3b383eff2f2e.png)


## クエリパラメータ



## STEP1. メール取得

OutlookのHTTP要求の送信モジュールを使って情報を取得します。

URLにはGraph APIを指定します。

`https://graph.microsoft.com/v1.0/me/mailFolders/Inbox/messages?$select=subject,receivedDateTime,categories&$top=10`


https://learn.microsoft.com/ja-jp/graph/query-parameters?tabs=http

https://qiita.com/PowerPlatform4/items/ed8cacf6eb2ce9816d68




![CleanShot 2025-05-22 at 23.48.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/24017225-7b98-4f0f-ba0f-e8b394f7026d.png)
![CleanShot 2025-05-22 at 23.52.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/0386b3eb-7198-49a8-bcf3-e61f154d54c7.png)

```json
{
  "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users('xxxxxxx')/mailFolders('Inbox')/messages(subject,receivedDateTime,categories)",
  "value": [
      {
          "@odata.etag": "W/\"xxxxxxxx\"",
          "id": "xxxxxx",
          "categories": [],
          "receivedDateTime": "2025-05-22T06:07:39Z",
          "subject": "結果確認メール（Automate）"
      },
      {
          "@odata.etag": "W/\"xxxxxxxx\"",
          "id": "xxxxxxxx",
          "categories": [],
          "receivedDateTime": "2025-05-22T06:07:19Z",
          "subject": "Text Recognition results"
      }
  ]
}
```



### STEP2. カテゴリを文字列化する

`json()`関数を使うことでカテゴリの情報を文字列として扱うことができます。

`join(<ここに動的コンテンツを指定>,',')`という使い方になり、画像のように式を入れるフォームで`Body Categories`を指定します。

> join(items('For_each')?['categories'],',')
> 
> ![CleanShot 2025-05-23 at 00.45.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/5dcec149-2e94-4468-beca-549e137f28b0.png)

> ![CleanShot 2025-05-23 at 00.46.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/4c9682c6-fe3a-45b6-98d0-fcb567ca15be.png)


#### Tips: 文字列追加だと

条件分岐で"じゃがいも"というタグがあるメールの情報に対して処理をしたいときに、カテゴリの文字列変数から条件分岐をしようとして"文字列変数に追加"のモジュールを選んで実行していました。

> ![CleanShot 2025-05-23 at 00.27.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/ca668f57-9a6f-4e2e-855b-331cc648d602.png)

...が、これだと変数に追加されていってしまいます。

`じゃがいも返信来てない,じゃがいも美術館,じゃがいも返信来てない,Blue category返信来てない,Blue category返信来てない,Blue category返信来てない,Blue category返信来てない,Blue category / じゃがいもカテゴリ`

> ![CleanShot 2025-05-23 at 00.46.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/97e41728-a042-472d-9923-7e1a4754b1a4.png)

全てのカテゴリ情報が連結されちゃうので"じゃがいも"のカテゴリではないメールにもじゃがいもカテゴリ判定になってしまっていました。




### STEP3.
Aligning Mandarin Speech Using Kaidi - Year 3

最近、中国語の音声と文字の対応を自動的に揃える「強制アラインメント（Forced Alignment）」という作業を試してみました。
音声認識エンジン「Kaldi」を使っての挑戦になりますが、今も何してるのかよくわからないので、一旦文字に起こしていきます。

やりたいこと
音声データ（たとえば「夜色如墨」など）と、その文字データ（中国語）を結びつけて、
「どの音がどこで発音されているか」を自動で揃えられるようにしたい。

今回の最終目標は「発音評価の参考にしたい」ですが、語学学習アプリの基礎素材づくり、音声付き字幕を作りたいにも応用できるまぁまぁいろんな目的でも役に立つ作業です。

使用するツール

Kaldi：音声認識エンジン（Linux/macOSなどで動作）
Python：データ準備用のスクリプト作成に使用
Text-to-Speech（TTS）ツール：最初の中国語音声を生成するために利用（今回はwebベースのTTSを使用）

エディタ　VSCode　私はこの子とcolabしかわかりません故

フォルダ構成
plaintext
コピーする
編集する
kaldi/
└── egs
    ├── audio/   ← .wav音声をここに置く
    ├── txt/     ← 音声に対応する.txtファイル（スペース区切り）
    ├── data
    └── train/  ← Kaldi用のデータファイル（後述）を生成する場所
└── s5/
    └── local/
        └── prepare_data.py  ← Pythonスクリプト
        
音声とテキストの準備
音声：.wav形式、16kHz、モノラルを推奨。今回はTTSで数本作成（300〜400字を4本ほど。wavしか求めてないのにmp3でお出ししてくるtext to speechの多いこと）

テキスト：1ファイルにつき1文。漢字の間にスペースを入れることで、Kaldiが音節ごとに分解しやすくなります。

例：
夜色如墨　→ 夜　色　如　墨　みたいな作業を黙々と。
Kaldi用のファイル作成
Kaldiは下記のようなファイルを使って音声とテキストを結びつけます：

ファイル名	内容
wav.scp	発話IDと音声ファイルのパス
text	発話IDと対応するテキスト
utt2spk	発話IDと話者IDの対応
spk2utt	話者IDと発話IDの対応（逆引き）

これをPythonスクリプトで自動生成するコードを作りました。でもuttとspkは今のところいらないという。

Pythonスクリプトの概要
以下のような処理をします：

txt/とaudio/フォルダから対応するファイルを探す
テキストファイルをスペース区切りで読み取り
Kaldiに必要な4つのファイル（wav.scp, text, utt2spk, spk2utt）をdata/trainに出力

python

```
wav_scp.append(f'{utt_id} {wav_path}')
text.append(f'{utt_id} {transcription}')
utt2spk.append(f'{utt_id} speaker1')
```

実行手順
ターミナルで以下のように操作しました：

bash

```
cd kaldi/egs/s5/local
python prepare_data.py
```
bash

```
utils/fix_data_dir.sh data/train
```

これを打つことにより整合性チェックも完了。

現時点での感想
Kaldiは情報が多いけど、中国語で使うとなると一気に資料が減るので、（あと中国語のサイトは探すのも翻訳込みでも読むのも難しい）手探り感が強かった。
スクリプト化しておくと、次からは音声とテキストを用意するだけで済むので楽。
データ数が少ないとアラインメントの精度も落ちるのでもう少し集め方は考慮すべき。
ただただ面倒臭いが、案外嫌いじゃない作業。
ubuntu22.04にbambu studioを入れる方法

# Ubuntu22.04にbambu studioを入れる方法

1. `Flatpak`を使ってbambu studioを入れる。以下のコマンドでflatpakが入る。
```
sudo apt install flatpak
sudo apt install gnome-software-plugin-flatpak
flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
```
2. 再起動してbambu studioをインストール
```
flatpak install flathub com.bambulab.BambuStudio
```
以上

* 参考文献\
[Flothubインストール](https://flathub.org/setup/Ubuntu)\
[bambu studio](https://bambulab.com/ja-jp/download/studio)
Atcoder解いてみた ABC 071 B - Not Found

# ABC 071 B - Not Found 解いてみた
問題は[こちら](https://atcoder.jp/contests/abc071/tasks/abc071_b)

## 回答
```C++
#include <iostream>
#include <string>
#include <map>
using namespace std;

int main() {
    string S;
    cin >> S;

    map<char, char> sMap;
    string refStr = "abcdefghijklmnopqrstuvwxyz";

    for (auto it = S.begin(); it != S.end(); ++it) {
        sMap[*it];
    }

    if (sMap.size() == 26) {
        std::cout << "None" << std::endl;
    }

    for (auto it = refStr.begin(); it != refStr.end(); ++it) {
        if(sMap.find(*it) == sMap.end()){
            std::cout << *it << std::endl;
            break;
        }
    }

    return 0;
}
```
Pythonの「ミュータブル」と「イミュータブル」を整理してみた

# Pythonの「ミュータブル」と「イミュータブル」を整理してみた

Pythonを使っていると、「ミュータブル（mutable）」と「イミュータブル（immutable）」という言葉に出会うことがあります。

久々にその言葉を聞いた時に、ミュータブルとイミュータブルってなんやったっけとなったので、その違いを備忘録としてまとめました。Python初心者の方にも参考になればうれしいです。

---

## 🔁 ミュータブル（mutable）

> 作成したオブジェクトの**状態を変更できる**性質のこと。

以下のような型がミュータブルに該当します：

- `list`（リスト）
- `dict`（辞書）
- `set`（集合）

### ✅ リストの例

```python
my_list = [1, 2, 3]
my_list.append(4)     # 要素を追加
my_list[0] = 10       # 要素を変更
print(my_list)        # 出力: [10, 2, 3, 4]
```

### ✅ リストの参照渡し
```python
a = [5]       # メモリ上に [5] というリストオブジェクトを作成
b = a         # 新しいリストオブジェクトは作成されず、b も a と同じオブジェクトを参照
b.append(10)  # b が参照しているリストオブジェクト自体を変更
print(a)      # 出力: [5, 10]
```

### ✅ 辞書の例
```python
my_dict = {'a': 1, 'b': 2}
my_dict['c'] = 3       # 新しいキーと値を追加
my_dict['a'] = 10      # 既存の値を変更
print(my_dict)         # 出力: {'a': 10, 'b': 2, 'c': 3}
```

### ✅ 集合の例
```python
my_set = {1, 2}
my_set.add(3)          # 要素を追加
my_set.remove(1)       # 要素を削除
print(my_set)          # 出力: {2, 3}
```

## 🔒 イミュータブル（immutable）
> 作成したオブジェクトの状態を変更できない性質のこと。
変更しようとすると、新しいオブジェクトが作成されます。

以下のような型がミュータブルに該当します：

- `int`（整数などの数値型）

- `str`（文字列）

- `tuple`（タプル）

### 🔸 数値の例
```python
x = 5
y = x
y = y + 1              # yは新しいオブジェクトを参照
print(x)               # 出力: 5
print(y)               # 出力: 6
```

### 🔸文字列の例
```python
s1 = "hello"
s2 = s1
s2 = s2 + " world"     # 新しい文字列オブジェクトを作成
print(s1)              # 出力: hello
print(s2)              # 出力: hello world
```

### 🔸タプルの例
```python
my_tuple = (1, 2)

my_tuple[0] = 10     # エラーになります
# TypeError: 'tuple' object does not support item assignment

my_tuple2 = my_tuple + (3,)  # 新しいタプルが作成される
print(my_tuple)              # 出力: (1, 2)
print(my_tuple2)             # 出力: (1, 2, 3)
```

## 💡 おわりに
Pythonの「ミュータブル」と「イミュータブル」は、データの扱いやバグの原因を理解する上でとても重要な概念です。
どちらが「変更可能」なのか迷ったときは、このページを思い出してみてください！
Playwright + TOTPでPomerium + Okta認証を自動化してみた

# はじめに

社内環境にアクセスするためのJump Serverに、**Pomeriumゲートウェイ＋Okta認証**を通して接続する必要があり、毎回の手動認証に手間を感じていました。

そこで、**Playwright + TOTP（Time-based One-Time Password**を用いて、**OktaのMFA認証を自動化**し、**Pomerium経由のTCP接続を自動起動**する仕組みを構築したので紹介します。

# 解決したかった課題

* Pomeriumを起動すると、Oktaログイン→MFA認証→トンネル確立の流れが手動
* 特に**毎回手でOkta Verifyコードを入力するのが面倒**
* 開発/運用チームのメンバーも手動対応しており、属人化していた

# 技術スタック

* `Playwright`: ブラウザ自動操作（Oktaログイン処理）
* `otplib`: TOTPコード生成（Okta Verifyコード自動入力）
* `child_process.spawn`: Pomeriumバイナリの起動
* `chromium` (via Playwright): headlessブラウザ操作
* Node.js (TypeScript)

#  処理フローの全体像

1. Node.jsからPomeriumバイナリをspawn
2. stderrから認証URLを取得
3. PlaywrightでそのURLにアクセス
4. ユーザー名＋パスワードを入力してログイン
5. Okta Verifyに切り替え、TOTPコードを自動入力
6. 認証完了でPomeriumがトンネルを確立

# 1. Pomerium起動とURLの取得

```ts
public initPomerium(): Promise<void> {
  const pomeriumProcess = spawn(pomeriumPath, [
    "tcp", pomeriumHost,
    "--listen", `:${pomeriumPort}`,
  ]);

  pomeriumProcess.stderr.on("data", async (chunk) => {
    const message = chunk.toString();

    if (message.includes("listening on")) {
      Logger.success(`Pomerium is ready on port ${pomeriumPort}`);
      resolve();
    } else if (message.includes("https")) {
      const match = message.match(/https?:\/\/[^\s]+/g);
      if (match) {
        await Playwright.loginPomerium(match[0]);
      }
    } else {
      reject(new Error(`Failed to start Pomerium: ${message}`));
    }
  });
}
```

* **stderr**から`https://`で始まるURLを抽出 → Pomeriumのログインページ
* Macでは`chmod`と`xattr`で初回実行制限を解除しているのもポイント

# 2. PlaywrightによるOktaログイン自動化

```ts
public async loginPomerium(url: string) {
  const browser = await chromium.launch({ headless: false });
  const page = await browser.newPage();
  await page.goto(url);

  await page.getByRole("textbox", { name: "Username" }).fill(credentials.SSH_USERNAME);
  await page.getByRole("textbox", { name: "Password" }).fill(credentials.JUMP_SERVER_PASSWORD);
  await page.getByRole("button", { name: "Sign in" }).click();

  await page.getByRole("link", { name: "Select to enter a code from" }).click();

  const otpInput = await page.getByRole("textbox", { name: "Enter code from Okta Verify" });
  const mfaOtp = Okta.generateOTP();  // otplibなどを使って生成
  await otpInput.fill(mfaOtp);
  await page.getByRole("button", { name: "Verify" }).click();
}
```

* ログインページ→Okta Verifyへの遷移→TOTP入力→認証完了の流れを再現
* `Okta.generateOTP()`は `otplib` 等で事前に設定されたシークレットから生成できます

```ts
import { totp } from "otplib";

export const Okta = {
  generateOTP(): string {
    return totp.generate(process.env.OKTA_MFA_SECRET || "");
  }
};
```

TOTPのセットアップはこちら：

https://qiita.com/oharu121/items/91e35ee7a31cfd80ef7e
# 成果と今後の展望

* Oktaログイン～MFA認証の自動化で、Pomeriumトンネル確立を**完全自動化**
* 毎回の認証手間がゼロに。**10秒以内にSSHが使える状態に！**
* 今後はGitHub Actionsなどから自動でVPN経由ジョブを走らせる応用も検討

PomeriumやOktaの認証処理が面倒…という方は、**Playwright＋TOTP**による自動化をぜひ試してみてください！
開発者が New Relic の CodeStream を使うことでダッシュボードが確認できるように

　CodeStream を活用することで VSCode や Jetbrains 等の IDE 上でダッシュボードが確認できるようになりました。New Relic の CodeStream は開発者が New Relic 上のテレメトリーデータへアクセスできるようにすることで高品質なソフトウェア開発とトラブルシューティングの効率化を実現するIDEの拡張機能です。

:::note info
最新のアップデートの詳細はこちら
[New Relic アップデート一覧
](https://newrelic.com/jp/blog/nerdlog/new-relic-update  "New Relic アップデート一覧")
:::

:::note info
無料のアカウントで試してみよう！
[New Relic フリープランで始めるオブザーバビリティ！](https://qiita.com/ktst79/items/5ee74b34e6adb8a7a6fa)
:::

CodeStream を利用するための初期設定はこちらの記事を参考にしてください。

https://qiita.com/T_OMORI/items/0bb538095c36ba662948

# 今回のポイント
CodeStream のアップデートのポイントは、次の２つです。
## 1\. ダッシュボード一覧から選択が可能
　CodeStream にログインして右上にあるアイコンからダッシュボードのアイコンを選択するとダッシュボードの一覧が表示されます。お気に入りの選択は New Relic の UI 上で設定したものがそのまま表示されます。

<img width="350" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3043202/09fdde64-899a-4b89-ace3-75980d75d39a.png">

![dashboard_list.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3043202/0aa2ffa8-4da4-4f4a-9da7-231356afa1b0.png)

 
## 2\. New Relic 上で作成したダッシュボードを IDE 上で直接表示
　一覧から選択すると New Relic 上で作成したダッシュボードを IDE 上で直接確認できるようになりました。タブやテンプレート変数も使用することができます。開発に使用している IDE をそのまま利用できるため、システムの可能状況を確認する際もツールを切り替えることなく確認できるようになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3043202/7330919c-32cb-4dd5-b55c-26c82586e5b0.png)

残念ながらフィルターは使用できないため、Facet Linking の機能は利用できません。

# まとめ
　今回の機能アップデートにより CodeStream を使ってテレメトリーデータにアクセスする選択肢が増え、ユースケースに合わせた利用ができるようになりました。CodeStream を活用して開発者も運用者と同じデータにアクセスしてチーム間のコミュニケーションの効率化を図りましょう。

　CodeStream は、NRQLの実行やログの検索にも対応しています。こちらの記事もぜひ参考にしてください。

 https://qiita.com/T_OMORI/items/010166189b691a03fb1d

 https://qiita.com/T_OMORI/items/39a754244345275ef9ac

　New Relicでは、**新しい機能やその活用方法**について、QiitaやXで発信しています！
**無料でアカウント作成**も可能なのでぜひお試しください！

:::note info
New Relic株式会社の[X(旧Twitter)](https://x.com/NewRelicJapan) や [Qiita OrganizationOrganization](https://qiita.com/organizations/newrelic)では、
新機能を含む活用方法を公開していますので、ぜひフォローをお願いします。
:::

:::note info
無料のアカウントで試してみよう！
[New Relic フリープランで始めるオブザーバビリティ！](https://qiita.com/ktst79/items/5ee74b34e6adb8a7a6fa)
:::

[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535230/66d6a010-e4fe-4004-a09b-c01eaad5a614.png)](https://newrelic.com/jp/contact-sales)
Power Automateの変数初期化エラー（'InitializeVariable' cannot be nested in an action of type 'For_each'）のメモ 


Power Automateの変数の初期化をしようとしたときに出たエラーです。

こんな感じでエラーでした。

> 'InitializeVariable' cannot be nested in an action of type 'For_each'

```json
{
 "title": "Node.jsのメモ",
 "tags": ["Node.js","JavaScript"]
}
```

こんな雰囲気のAPIから返ってきたAPIを処理する際に"tags"の中が配列でPA的に強制ループが発生するようなタイミングの話です。

> ![CleanShot 2025-05-23 at 00.08.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/8735afce-0f34-47a8-91a0-91c329fee6cf.png)
> 
> フローの保存がコード 'InvalidVariableInitialization' およびメッセージ 'The variable action '変数を初期化する' of type 'InitializeVariable' cannot be nested in an action of type 'For_each'.' で失敗しました。


## ダメなパターン

そもそも仕様的にこの配置がNGな模様。たぶん。

> ![CleanShot 2025-05-23 at 00.12.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/1b1247f7-9f9b-4377-b2a6-3888f6c6ea6f.png)

## OKなパターン

変数の初期化をFor eachのループ外に定義して、その変数をループ内で上書きして使うという使い方

> ![CleanShot 2025-05-23 at 00.13.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/99046514-e594-4c46-aa5d-b6cf4d444b7c.png)

## まとめ

変数のスコープが柔軟さはない仕様っぽいです。世界観問題な気がする。

JSONなどで変数を保存するときは要注意。ループ使わないように式でどうにかできるときはそっちも良さそう
配列・連想配列とは

# 配列(Array)
同じ型のデータを連続して格納するためのデータ構造
配列の各要素は、インデックスを使用してアクセスされる
固定サイズで宣言される
```
例)
int[] numbers = {1, 2, 3, 4, 5};
```
# 連想配列(Associative Array)
キーと値のペアを格納するデータ構造
キーを使用して、対応する値にアクセスする
サイズは動的に変更可能
```
例)
Map<String, Integer> ageMap = new HashMap<>();
```
# ※インデックス
配列の要素にアクセスするために使用される整数値
配列内の要素の位置を示す
# ※キー
連想配列の要素にアクセスするために使用される識別子
git push 時の HTTP 400 エラーの対処法

## はじめに
`git push`コマンド実行時に以下のようなエラーメッセージが表示されました。今回は、このエラーの原因と解決策をまとめます。

```zsh
Enumerating objects: 4368, done.
Counting objects: 100% (4368/4368), done.
Delta compression using up to 8 threads
Compressing objects: 100% (4144/4144), done.
Writing objects: 1% (83/4367), 112.00 KiB | 57.00 KiB/s
error: RPC failed; HTTP 400 curl 22 The requested URL returned error: 400
fatal: the remote end hung up unexpectedly
Writing objects: 1% (83/4367), 1.07 MiB | 447.00 KiB/s
```


## エラーの原因
GitがHTTPプロトコルを使用してデータを送信する際のバッファサイズがデフォルト（約1MB）では小さすぎるため発生したようです。
今回は、node-modulesなどの容量の大きなディレクトリが含まれていたことが原因でした。

:::note 
長期間コミットせずに多くの変更を行った場合も、同様のエラーが発生することがあります
:::

## 解決方法
そこでとった対応は、以下の２点です。
- `.gitignore`に大容量のディレクトリを追記
- Gitのバッファサイズを増やす

`.gitignore` に `node-modules`などのディレクトリを追記しました
```.gitignore
node_modules/
.next/
```

そして、一時的な対応としてHTTPプロトコル経由でのデータ送信に使用されるバッファサイズを <strong>約500MB</strong> に設定しました。
```zsh
git config http.postBuffer 524288000
```

上記のコマンドを実行し、改めて`git push`したところ無事成功しました！

```zsh
git push -u origin main

Writing objects: 100% (4367/4367), 18.24 MiB | 3.76 MiB/s, done.
Total 4367 (delta 1186), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (1186/1186), done.
```

## その他の解決方法
バッファサイズの調整でも解決しない場合は、以下の方法もあるようです。

- 分割してプッシュする
- HTTPSの代わりにSSHプロトコルを使用する

## まとめ
これまでは機械的に `.gitignore` に `node_modules` を記載していましたが、今回のエラーを通じてその必要性を改めて理解しました。


## 参考

https://qiita.com/redrabbit1104/items/efd35b763b311ad53964

https://zenn.dev/ykesamaru/articles/b9f596703aff85

https://kumakake.com/github%E3%81%AEpush%E3%81%A7400%E3%82%A8%E3%83%A9%E3%83%BC%E3%81%8C%E5%87%BA%E3%81%BE%E3%81%99/
`git fetch origin` と `git pull origin main`はどう違う？

# 違いを一言で言うと？

| コマンド                   | 説明                      |
| ---------------------- | ----------------------- |
| `git fetch origin`     | **最新情報だけを取得する（更新はしない）** |
| `git pull origin main` | **最新情報を取得して、即マージする**    |

# それぞれの動作の違い

### 🧩 `git fetch origin`

* リモートの最新情報を**ローカルの追跡ブランチにだけ反映**する
* **現在の作業ブランチには影響を与えない**
* コードは更新されない

```text
(main ← 作業中)
(origin/main ← fetchで更新された)
```

### 🧩 `git pull origin main`

* `fetch` のあとに自動で `merge`（または `rebase`）を行う
* **現在のブランチに直接変更が加わる**

```bash
# fetch + merge を一度に実行
$ git pull origin main

# 実質的にこれと同じ
$ git fetch origin
$ git merge origin/main
```

# 実用例と使い分け

### ✨ `git fetch origin` が向いているとき

| シーン                              | 理由                         |
| -------------------------------- | -------------------------- |
| PR前に差分や履歴を確認したいとき                | 作業中のブランチを壊さずにmainを確認できる    |
| `git rebase origin/main` を使いたいとき | fetch後にrebaseすれば履歴がきれいに保てる |
| コードは更新せずに最新状態を追跡したいとき            | チームのmainに何が入ったかだけを知りたい     |

### 🚀 `git pull origin main` が向いているとき

| シーン                     | 理由                  |
| ----------------------- | ------------------- |
| 今すぐ最新のmainを取り込んで作業を続けたい | 手動でmergeしなくても即反映される |
| 一人で作業中で履歴を気にしない         | merge履歴ができても問題ない    |

# `git pull --rebase` ってなに？

```bash
$ git pull --rebase origin main
```

* `fetch` + `rebase` の組み合わせ
* 履歴がシンプルに保たれるので、チーム開発ではおすすめ


# 結論：安全なワークフローなら

```bash
# 最新状態を取得（ローカルはそのまま）
git fetch origin

# 最新mainに追従（履歴きれい）
git rebase origin/main
```

> 履歴をきれいに保ちたいなら「fetch → rebase」
> とにかく今すぐ最新にしたいなら「pull」
なぜ`git rebase main`を使うのか？

# はじめに

`git rebase main` は、複数人で開発しているときに**自分の作業ブランチを最新の`main`に追従させる**ためのコマンドです。

「`git merge` じゃダメなの？」
「rebaseって履歴が書き換わるって聞いたけど怖い…」

そんな疑問を持つ方向けに、この記事では `git rebase main` を使う**理由・タイミング・注意点**をわかりやすく紹介します。

# mainから分岐したまま作業していると…

例えば以下のように `main` に新しいコミットが追加されたとします：

```
A---B---C   (main)
     \
      D---E  (feature/my-task)
```

このまま `feature/my-task` をPRとして出すと、**古い`main`に基づいたコード**がレビューされてしまい、**最新の状態と衝突する**可能性があります。

# 解決策：最新の`main`に追従させる

```bash
$ git fetch origin
$ git rebase origin/main
```

これにより以下のように履歴が付け替わります：

```
A---B---C   (main)
         \
          D'--E' (feature/my-task)
```

※ `D` と `E` の内容はそのまま、**親が最新の`C`に変更された**イメージです。

# `merge`との違い

| 比較項目        | `git merge main`   | `git rebase main`  |
| ----------- | ------------------ | ------------------ |
| 履歴の見た目      | マージコミットが入る（分岐が見える） | 線形（シンプルな1本線）になる    |
| 利用の目的       | 変更を取り込む            | 履歴を整理して追従させる       |
| コンフリクト時の修正順 | 自分の作業内容 vs main    | mainの変更 vs 自分の作業内容 |
| チーム開発での使用   | PR前の整理には不向き        | PR前の整理に◎（レビューしやすい） |

# rebase の使い方（基本）

```bash
# 1. 最新mainを取得
$ git fetch origin

# 2. 作業ブランチでrebase
$ git checkout feature/my-task
$ git rebase origin/main
```

# コンフリクトが出たら？

1. 該当ファイルを手動で修正
2. 修正が終わったら：

```bash
$ git add .
$ git rebase --continue
```

3. 途中でやめたいとき：

```bash
$ git rebase --abort
```

🧼 PR前にやると何が嬉しい？

* ✅ mainの最新コードに追従することで**衝突の予防**
* ✅ PRの履歴が「自分の変更だけ」になり、**レビューしやすい**
* ✅ 意図しない差分が紛れ込むのを防げる

# `rebase`は**共有前**に使う！

* `git rebase` を使うと、**コミットの履歴が書き換わります**（見た目は同じでも、別のコミットとして扱われる）
* そのため、**すでに`push`したブランチに対して`rebase`すると、履歴のズレが発生**し、他の人との整合が取れなくなります

>  **「まだ他の人と共有していないブランチ」でだけ使うのが基本！**

もしすでに GitHub に `push` していて、**その後にrebaseを実行した場合**は…

```bash
$ git push --force-with-lease
```

のように、\*\*強制的に履歴を上書き（force push）\*\*する必要があります。

🧱 なぜ危険なの？

* 他のメンバーがそのブランチを元に作業していると、**履歴の不一致でマージやpullができなくなる**
* 最悪の場合、**他人の作業を上書きしてしまうリスク**も
✅ 安全な運用ルール（おすすめ）

| 状況                 | rebaseしてOK？ | 補足                         |
| ------------------ | ----------- | -------------------------- |
| ローカル作業中だけのブランチ     | ✅ 安全        | PR前にrebaseで履歴整理しよう         |
| push済みだがまだ誰にも見せてない | ✅ 条件付き      | `--force-with-lease` で上書き可 |
| チームで共有中のブランチ       | ❌ 原則NG      | `merge`で済ませるのが安全           |

# まとめ

| やりたいこと                  | コマンド例                         |
| ----------------------- | ----------------------------- |
| 作業ブランチを最新mainに追従        | `git rebase origin/main`      |
| rebase途中で止める            | `git rebase --abort`          |
| rebase完了後、force pushが必要 | `git push --force-with-lease` |

> 「きれいな履歴を保ちつつ、最新のコードで安心してPRを出す」
> それが `git rebase main` の最大のメリットです！
作業ブランチを元に戻したい？git checkout .とgit cleanの使い分けを解説！

# はじめに

「間違えてファイルを編集してしまった…」
「不要なファイルを追加してしまった…」
そんなとき、Git には**変更をまるっと元に戻す便利なコマンド**があります。

この記事では、以下2つのコマンドを例付きで解説します。

* `git checkout .`：**編集内容の取り消し**
* `git clean`：**新しく追加されたファイルの削除**

# 作業中にこんな状態になったとき…

```bash
$ git status

Changes not staged for commit:
  modified:   src/index.js

Untracked files:
  temp.txt
  dist/
```

やってしまった！

* `src/index.js` を変えすぎた…
* `temp.txt` や `dist/` は生成ファイルでいらない…

# `git checkout .`：編集だけを元に戻す

```bash
$ git checkout .
```

📌 これは **ステージされていない変更（編集）をすべて破棄** します。

* ✅ `modified` 状態のファイルを元に戻す
* ❌ `untracked` なファイル（Git管理外の新規ファイル）は対象外

🔍 たとえば `src/index.js` だけが初期状態に戻ります。

# `git clean`：未追跡ファイルを削除する

```bash
$ git clean -fd
```

| オプション | 説明               |
| ----- | ---------------- |
| `-f`  | force（削除を明示的に許可） |
| `-d`  | ディレクトリも削除対象に     |

📌 これは **Git に追加されていないファイル・フォルダを一括削除** します。

* ✅ `temp.txt` や `dist/` のような untracked ファイルを削除
* ❌ Git 管理下のファイルには影響しない

:::note info
補足：実行前の安全確認 `--dry-run`
:::

```bash
$ git clean -fd --dry-run
```

👀 実際に削除されるファイルを確認できます（削除は行われません）。

# 両方を使えば「まっさら」状態に

```bash
$ git checkout .
$ git clean -fd
```

これで以下のような状態に戻ります：

* 編集したファイル：**元通り**
* 新規で追加したファイル：**削除**

# まとめ

| やりたいこと             | コマンド                              |
| ------------------ | --------------------------------- |
| 編集をすべて取り消したい       | `git checkout .`                  |
| 未追跡ファイルを削除したい      | `git clean -fd`                   |
| 削除されるファイルを事前に確認したい | `git clean -fd --dry-run`         |
| 編集も未追跡ファイルも全部戻したい  | `git checkout . && git clean -fd` |

> 「とりあえず元に戻したい！」ときの最終兵器セットがこれ。
> でも本当に戻していいか、`--dry-run` で一度確認するのを忘れずに！
Raspberry PiのカーネルソースをWindows (wsl)でクロスコンパイルする

Raspberry Piのカーネルバージョンを手っ取り早く最新にしたい時などの為に、ソースビルドして導入する方法をまとめます。なお、本解説は64bit(Aarch64)版カーネルで検証した内容です。

コンパイルにはWindows母艦PC上のwslを用います。

# 依存関係をインストールする

```bash
sudo apt install git bc bison flex libssl-dev make libc6-dev libncurses5-dev
sudo apt install crossbuild-essential-arm64
```

# ソースのクローン
公式のGitHubからカーネルソースを引っ張ってきます。

```bash
git clone --depth=1 https://github.com/raspberrypi/linux
cd linux
```

# 環境変数と `.config` の準備

```bash
# Raspberry Pi 3/3+/CM3/CM3+/Z2W/4/400/CM4/CM4S
KERNEL=kernel8
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- bcm2711_defconfig
```

```bash
# Raspberry Pi 5/500/CM5
KERNEL=kernel_2712
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- bcm2712_defconfig
```

KERNELは後ほどカーネルイメージをコピーする際に出てきます。

# ビルド

```bash
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- Image modules dtbs -j8
```

`-j8`はCPUのスレッド数に合わせて任意で変更します。

# 転送
丸ごと送るのでかなり時間がかかります。
もっと賢いやり方があるかもしれない？
```
scp -r ~/linux pi@[Rapberry PiのIP]:/home/pi/
```

# インストール
Raspberry Pi側での実行

```bash
cd linux
sudo make -j6 modules_install
sudo cp /boot/firmware/$KERNEL.img /boot/firmware/$KERNEL-backup.img
sudo cp arch/arm64/boot/Image.gz /boot/firmware/$KERNEL.img
sudo cp arch/arm64/boot/dts/broadcom/*.dtb /boot/firmware/
sudo cp arch/arm64/boot/dts/overlays/*.dtb* /boot/firmware/overlays/
sudo cp arch/arm64/boot/dts/overlays/README /boot/firmware/overlays/
```

# カーネルモジュール単位でビルド・転送する
例：`drivers/media/usb/em28xx/`のドライバをコンパイルし転送する

```bash
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- M=drivers/media/usb/em28xx modules
scp -r ./drivers/media/usb/em28xx/ pi@[Rapberry PiのIP]:/home/pi/linux/drivers/media/usb/
```


# 参考
[Raspberry Pi Documentation: The Linux kernel](https://www.raspberrypi.com/documentation/computers/linux_kernel.html)
Linux アセンブリ 入力を受け付け画面表示

## 検証画面
```
nasm -f elf64 test.asm -o test.o
ld test.o -o test
./test
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4054974/95e35483-c521-4e84-8ec7-7c4bcc180470.png)

## コード
```
section .text
global _start

_start:
    ; 標準入力から読み取り
    mov rax, 0          ; sys_read システムコール番号
    mov rdi, 0          ; 0=標準入力
    mov rsi, buffer     ; バッファのアドレス
    mov rdx, 1024       ; 読み取る最大バイト数
    syscall

    ; 読み取ったバイト数を保存
    mov rbx, rax        ; RAXには実際に読まれたバイト数が格納される

    ; 標準出力に書き込み
    mov rax, 1          ; sys_write システムコール番号
    mov rdi, 1          ; 1=標準出力
    mov rsi, buffer     ; 書き込むデータのアドレス
    mov rdx, rbx        ; 書き込むバイト数
    syscall

    ; プログラムの終了
    mov rax, 60         ; sys_exit システムコール番号
    mov rdi, 0          ; 終了ステータス
    syscall

section .bss
buffer resb 1024        ; 1024バイトのバッファを確保

```
Q11Q CSV Format v1.0 📄｜自己記述型CSV構文仕様書（QSv1）

当方でデータベースを取り扱うときに蓄積されたノウハウを構造化CSV "Q11Q CSV Format v1.0"（以下QSv1）として提案する。これは、従来のCSVの3行を追加し、データ型・列番号・列名を明示的に定義し、可搬性・自動変換性・エラー解析性を飛躍的に向上させる自己記述型フォーマットである。

---

## 0. 基本仕様

- 文字コード：UTF-8（BOMなし）を推奨
- 区切り文字（Delimiter）：**TAB（`\\t`）を推奨**
    - カンマ（`,`) は金額や小数点と衝突するため避けること
- 行区切り：CR+LF（Windows標準）またはLF（UNIX互換）両対応
- 可変長を想定している

## 1. 構造定義（標準構文）
※本来はタブ区切りを推奨するが、説明のため、コンマ区切りとしている。
```
0,1,2,3
TEXT(29),TEXT(3),DATE,CURRENCY
氏名,年齢,生年月日,給与
山田太郎,30,1990/01/01,500000
佐藤花子,27,1995/12/25,420000

```

### 各行の意味：

| 行番号 | 内容 | 説明 |
| --- | --- | --- |
| 1行目 | 列番号 | **0起算の固定インデックス**、列順を保証 |
| 2行目 | データ型 | 明示型（TEXT(N), DATE, NUMERIC等） |
| 3行目 | 列名 | フィールド名、予約語や重複も許容 |
| 4行目〜 | データ本体 | 実データ、型定義に従って処理される |


最初にデータ型が定義されているので、各データにはダブルクォーテーションは必要ない。

## 2. データ型定義一覧（標準推奨）

| 型名 | 意味 | 備考 |
| --- | --- | --- |
| TEXT(N) | 文字列（最大N文字） | Access, SQL用に直接変換可 |
| DATE | 日付型（YYYY-MM-DD） | ISO形式推奨 |
| CURRENCY | 金額型（整数） | AccessではCurrency型に変換 |
| NUMERIC(P,S) | 固定精度数（P桁, S小数） | adNumeric型やSQL Decimal変換可 |
| BOOLEAN | 真偽（-1/0またはTrue/False） | 必要時に解釈 |
| DOUBLE | 倍精度浮動小数点型 | 科学技術・統計処理に用いる |
| SINGLE | 単精度浮動小数点型 | 金利等の表示使用される |

---

## 3. Q11Q式の技術的利点（構造別）

### ■ 型安全性

- 値を見て型を推定しない（例："0" → True誤解釈を防止）
- TEXT行があるため、値にクォーテーションが不要
- タブ区切りにした場合、数字はコンマ付で表示可能

### ■ エラー特定性

- 列名が予約語・Nullでも処理可能
- "列3番の値 'abc' を DATE に変換できない" などの特定が明確

### ■ 処理汎用性

- `skiprows=2` でPandasなどに直接流し込める
- 列番号で処理できるため、列名の揺らぎに強い

### ■ 可搬性・拡張性

- Excel, Access, PostgreSQL, SQLite 等への移行が容易
- JSON Schema等不要。CSV単体で完結

---

## 4. 拡張運用（推奨）

- ファイル先頭に以下のコメント行を追加：
    
```text
    # Q11Q CSV Format v1.0
```
    
- 型行に `@INFER` を使うことで、スキーマ自動生成用マーカーとすることも可能（ツール連携時）

---

## 5. 利用例（SQL DDL生成）

上記CSVから以下のSQLが自動生成可能：

```sql
CREATE TABLE 顧客データ (
    氏名 VARCHAR(29),
    年齢 VARCHAR(3),
    生年月日 DATE,
    給与 MONEY
);
```

---

## 6. 実務補足（メタ情報記述指針）

- **型が不明な場合**：元のDB型名をそのまま2行目に記載しても良い（例：`VARCHAR2`, `nvarchar` 等）
- **単位の明示**：金額・体積・重さなどは、列名に `(円)`, `(kg)` のように単位を含めることを推奨
- **0埋め:**パディングが望ましいときは要件に定義すること
- **郵便番号型:**こうした出力書式の指定が必要な場合は要件を定義する事。郵便番号の他、電話番号等が考えられる。
- **緯度・経度**：方位（N/S/E/W）や表記形式（度分秒 vs 十進数）を列名または型に含めること

## 7. 結論

> Q11Q式CSV（SFv1）は、まだ改善の余地があると思われるものの、構造と意味を明示的に含んだ自己記述型CSVであり、従来の曖昧なCSVフォーマットに代わる実用的かつ極めて堅牢な構造定義方式である。また、データベースの構造についてもCSVを観るだけで理解が可能であり、元のデータベースとデータ型のVariantだけ要件を定義すればよく、マニュアルの記載も効率的となる。
> 

AI処理・ETL処理・Access変換・Python処理など、全領域で構文崩壊を未然に防ぐための基本構造として推奨される。

---

## 📩 SFv1へのご意見・導入報告フォーム（匿名・自由記述）

Q11Q CSV Format v1.0（QSv1）を導入された方、あるいは仕様をご覧になった方からのご意見・改善提案・活用事例などを広く募集します。Qiitaのコメント欄又は以下のフォームにお寄せください。

- **匿名可**・**メールアドレス不要**
- **1分程度**で送信可能
- **返信を希望される方のみ連絡先記入欄が表示**されます

📄 フォームはこちらから

👉 https://forms.gle/XF13ZrKidmPMNSCB8

みなさまからのフィードバックは、今後のSFv1仕様の進化・拡張・スクリプト提供の参考にさせていただきます。

🔖 Qiita記事アーカイブリンク
🪪 概要記事（第1回）
https://qiita.com/Q11Q/items/cc504d515a5592e605e3

📜 仕様本文（第2回）
https://qiita.com/Q11Q/items/c79321a8ab9d3b0a560a
from the QSv1 team
Maps JavaScript API のAPIキー入手方法と漏洩対策についての話

# Maps JavaScript API というAPIがある

Googleが提供しているAPIのひとつです。
これを使ってウェブページを作成すると、例えばページ内に**グーグルマップみたいな地図を表示させる**といったことができます。

正式名称は Maps JavaScript API ですが、Qiitaなどの解説記事では Google Map API と呼ばれているのをよく見かけますね。

# APIキーが必要なタイプのAPIとなっている

Maps JavaScript API を使うには**APIキー**、いわばパスワードのようなものが必要です。
パスワードを知っている人だけが地図表示できるというわけですね。

世の中にはAPIキーを必要としないAPIもあるのですが、Maps JavaScript API には必要です。

# Maps JavaScript API のキー発行は Google Cloud で！

そもそも Maps JavaScript API は [Google Cloud](https://cloud.google.com/) の機能の一部です。

Google Cloud で「プロジェクト」をひとつ作るという手順を踏むことで、APIキーを入手できます。

プロジェクト作成の手順はこちら（↓）の記事が分かりやすいです。

https://qiita.com/Haruka-Ogawa/items/997401a2edcd20e61037#2-api%E3%82%AD%E3%83%BC%E5%8F%96%E5%BE%97

ちなみに、勤務先など何らかの組織に属しているGoogleアカウントだと、組織の管理者がプロジェクト作成の操作を許可していないかもしれません。その場合、
「Google Cloud Platform サービスが無効になっています。Google Workspace 管理コンソールでサービスを有効にするには、管理者にお問い合わせください。」
というエラーメッセージが出てプロジェクトを作成できないので注意。

# ところでキーという仕組みがあるのはなぜ？

ChatGPTに質問してみたところ下記の回答を得ました。

> - 利用者の識別：誰がリクエストを送っているのかを把握
> - 利用制限の適用：1日〇回まで、などの制限を管理
> - 課金管理：利用量に応じて料金が発生するAPIでは、誰に請求するかを判別
> - 不正利用の防止：悪意ある第三者による利用を制限

キーが漏洩してしまうと、第三者がAPI使い放題になってしまいます。勝手にガンガン使われて、Googleから「使用料をお支払いください」と言われたら…。ああ、怖い。

# 漏洩対策をしよう

というわけで、漏洩しても大丈夫なように**キーの利用制限の設定**をしておくべきです。

Google Cloud の設定画面では、下記3種類の制限をかけることができます。

- **① HTTPリファラーの制限**
    - リファラーを制限して**自分のページだけがAPIを使えるようにする**
        - ※そもそもリファラーとは「リクエストがどのページから来たのか」という情報のこと
        - ※よそのページからAPIを使おうとする（制限に引っかかる）とエラー `RefererNotAllowedMapError` になる
- **② APIの制限**
    - 当該のキーで利用可能とするAPIの種類を **Maps JavaScript API だけに絞る**
- **③ 割り当ての制限**
    - APIを使える**回数の上限を定める**

# 万が一漏洩したらキーを再発行すればOK

Google Cloud には**APIキーのローテーション**という機能があり、いわばキーの再発行のようなことができます。

ローテーションすればそれまでの古いキーは使えなくなるので安心。

# キーはコードに直接記述すれば動作はするが…

さて、では入手したキーをどこでどうやって使うか、です。
最も簡単なのはキーをJavaScriptのコードに直接記述してしまうこと。これでAPIは動作し、地図表示ができます。

ローカル環境でさくっと動作確認するならばこのやり方で良いですね。

https://qiita.com/Haruka-Ogawa/items/997401a2edcd20e61037

さきほども紹介したこちら（↑）の記事でも、キーをコードに直接記述しています。

ところがこのやり方だと、ウェブページを公開したときにキーも一緒に公開されることになります。**自らキーを漏洩させている**ことになります！

https://cloud.google.com/docs/authentication/api-keys-best-practices?hl=ja

Google Cloud の公式ガイド（↑）にも、

> API キーをクライアント コードに含めたり、コード リポジトリに commit したりしない

と明記されていますね。

ビジネスの場で漏洩をやってしまうとマズイことになります。。。

キーを直接記述したコードをあえて公開するなら、趣味目的や学習目的で作ったキーだけにしておきましょう。もちろんその場合も、前述の制限はしっかり設定しておきましょう。

# 終わりに

APIキーについて調べるうちに新たな学びが次々とあって、Qiitaに情報整理しておきたい！と思って書いたのが当記事です。

結局「キーを漏洩させずにページ公開するにはどうすればいいか」が課題として残っているので、それについては今後学んでみようと思っています。

今回は以上です。
wandbでBus error (core dumped)が出たとき

# 環境
- OS: Ubuntu 22.04
- cuda: 12.1
- torch: 2.4.0
- wandb: 0.17.4

# 状況
PyTorch, wandbを用いた深層学習の学習コードを動かしていたら急に以下のエラーが多発して何も出来ないという状況になった．
```
Bus error (core dumped)
```

# 解決
デバックや確認用にwandbのログを入れていないコードを用意しており，そちらを動かした所普通に動く．

？？？となったのでとりあえずprintデバック．
そうすると以下の部分の手前ででていることが分かった．
複数のlossを記録するために`dict`型のlossesという変数のログを取っている箇所であった．
```python
wandb.log(losses) 
```

lossesが`torch.Tensor`を含んでいたことが怪しそうであり，ドキュメントに例が多く載っているfloatで記録してみることにした

このようにすると何の問題もなく動くようになった．
```diff
- losses:  dict[str, torch.Tensor]
+ losses = dict[str, float]
```
```python
wandb.log({k: v.item() if isinstance(v, torch.Tensor) else v for k, v in losses.items()})
```

※ドキュメントでは`dict[str, Any]`となっている
```python
log(
    data: dict[str, Any],
    step: (int | None) = None,
    commit: (bool | None) = None,
    sync: (bool | None) = None
) -> None
```


`Bus error`はC言語などで不正なメモリアクセスをしたときに出るようなものだと勝手に思い込んでいたのでまさかのwandbが原因で驚いた．




# まとめ
tensorのまま記録する元のコードは推奨されるべきではないと思うので，逆にしばらく学習が出来ていたことが不明．
wandbのlogはなるべくスカラーにする．誰かのお役に立てば幸いです．

numpyやPILを使って画像のログする方法もあるので，wandb.logの詳細はドキュメントを見てください．
https://docs.wandb.ai/ja/ref/python/log/