OmniAICreator/Qiita-1.07M huggingface dataset:
推定量の3つの重要な性質を直感的に理解する

統計学では、データから母数を推定する際に「推定量」という概念を使います。  
推定量には **不偏性・一致性・効率性** という3つの重要な性質があります。  
この記事では、それぞれの性質を直感的な例を使ってわかりやすく解説します。  

---

## **1. 不偏性（Unbiasedness） – 「平均すると正解に当たる」**  

### **不偏性とは？**  
推定量の **期待値（平均）が真の値に一致する** ことを指します。  
つまり、「何度も繰り返せば、長期的に見て正しい値に落ち着く」推定方法であれば、不偏性を持つといえます。  

### **直感的な例：的当てゲーム** 🎯  
- ある人が何回も矢を射って、的に当てるとします。  
- **不偏な推定量とは、平均すると的の中心（真の値）に当たるようなもの。**  
- 矢が的の周りに散らばっていても、「全体として真ん中を狙っている」なら不偏です。  

### **数値的なイメージ**  
サイコロを振って平均値を推定する場合、何度も試行すれば出目の平均は**理論上の期待値 3.5** に近づきます。  
この場合、推定量は不偏です。  

✅ **ポイント:**  
- 「推定値が常に正しい」とは限らない。  
- **繰り返せば正解に収束するなら不偏性がある。**  

---

## **2. 一致性（Consistency） – 「データが増えれば正解に近づく」**  

### **一致性とは？**  
サンプルサイズを無限に増やしたときに、**推定値が真の値に確率的に収束する** 性質のこと。  
データが少ないうちはバラつくかもしれないが、たくさん集めれば正しい値に近づく推定量を「一致推定量」といいます。  

### **直感的な例：モザイク写真** 📷  
- ぼやけたモザイク画像を見たとき、最初は何の画像かわからない。  
- しかし、解像度が上がる（データが増える）につれて、本来の画像（真の値）がはっきり見えてくる。  
- **一致性とは、このようにデータを増やせば正しい推定値に近づく性質。**  

### **数値的なイメージ**  
サイコロを5回振ると、平均は **3.5 にならないことが多い**。  
しかし **1000回振れば、平均はかなりの確率で 3.5 に近づく**。  
これは、一致性のある推定量の特徴です。  

✅ **ポイント:**  
- **データが少ないうちはブレるが、増やせば確実に真の値に近づく。**  
- どんなに小さなサンプルでも不偏な推定量は作れるが、一致性がないとデータが増えても正解に収束しない。  

---

## **3. 効率性（Efficiency） – 「ムダなく精度よく推定する」**  

### **効率性とは？**  
同じ不偏な推定量の中で、**推定値のバラつき（分散）が最も小さい** ものを効率的な推定量と呼びます。  
効率的な推定量ほど、**より少ないデータで精度よく推定** できます。  

### **直感的な例：ダーツの精度** 🎯  
- 2人がダーツを投げて、どちらも平均的には的の中心に当たる（＝不偏性を持つ）とする。  
- **Aさんの矢は的の中心にギュッと集まっているが、Bさんの矢は中心を狙いつつも広くバラついている。**  
- **Aさんの方がより「効率的」な推定をしている。**  
- つまり、**同じ「平均が正解に一致する」推定量の中でも、ブレが少ない（分散が小さい）ほうが効率的。**  

### **数値的なイメージ**  
- ある町の平均年収を推定するとする。  
  - **方法A:** 100人を無作為に選び、平均を求める。  
  - **方法B:** 100人の中に極端な高所得者・低所得者が多く含まれてしまう。  
- どちらの方法でも長期的に見れば「平均年収」は正しく推定されるが、**方法Aの方がデータのバラつきが少なく、より精度の高い推定ができる。**  
- **効率性とは「正解に向かうときのムダなブレが少ないこと」**  

✅ **ポイント:**  
- **正しい推定値を出すのに、できるだけ少ないデータで精度よく求められるほうが優秀。**  
- **「不偏だけどバラつく推定量」より、「不偏でバラつかない推定量」のほうが効率的。**  

---

## **まとめ：3つの性質を比較！**  

| 性質 | 直感的な説明 | 具体例 |
|------|------------|--------|
| **不偏性** | 平均すると正しい | 的当てゲームで、矢が全体的に中心を狙っている |
| **一致性** | データが増えれば正解に近づく | モザイク写真が解像度アップでクリアになる |
| **効率性** | ブレずに安定して推定できる | ダーツで同じ場所に当たるほうが精度が高い |

---

## **おわりに**
統計学において、推定量の **不偏性・一致性・効率性** は非常に重要な概念です。  
単に「正しい値を推定する」だけでなく、「ブレを少なく」「データが増えたら確実に収束する」といった観点が重要になります。  

この3つの性質を理解すると、推定量の選び方やデータ分析の精度向上に役立ちます。  
「より正確なデータ分析をしたい！」というときには、ぜひこの3つを意識してみてください！
C#でIoTプログラミング on ESP32 #3 - LED,PWM

今回のプログラムはLEDの明るさを徐々に変化させるプログラムを紹介します。
LEDの明るさをコントロールするためにPWM(Pulse Width Modulation:パルス幅変調)を使います。

## ハードウェア
・Freenove ESP32-S3-WROOM Board or Espressif ESP32-S3-DevKitC

## 導入するパッケージ
・nanoFramework.System.Device.Pwm
・nanoFramework.Hardware.Esp32

## プログラミング
・新規プロジェクトを作成します。プロジェクト名は「ESP32S3_Blink_PWM」としました。

・コードを入力する前にパッケージをインストールしてください。

・コードは次のようになります。
```C#:Program.cs
using nanoFramework.Hardware.Esp32;
using System.Device.Pwm;
using System.Threading;

namespace ESP32S3_Blink_PWM
{
    public class Program
    {
        //LEDを接続しているGPIO
        const int ledPin = 2;
        
        public static void Main()
        {
            //LEDピンにPWMを設定
            Configuration.SetPinFunction(ledPin, DeviceFunction.PWM1);

            //周波数40KHzとしてPWMを設定
            PwmChannel pwmChannel = PwmChannel.CreateFromPin(ledPin, 40000, 0);

            //PWMをスタート
            pwmChannel.Start();

            while (true)
            {
                //20ms毎に1%づつデューティ比を増やす。
                for(int i = 0; i <100;i++)
                {
                    //PWMのデューティ比は0.0～1.0で設定する。
                    pwmChannel.DutyCycle = (double)i / 100.0;       
                    Thread.Sleep(20);
                }
                //20ms毎に1%づつデューティ比を減らす。
                for (int i = 100; i > 0; i--)
                {
                    pwmChannel.DutyCycle = (double)i / 100.0;
                    Thread.Sleep(20);
                }
            }
        }
    }
}
```

・実行してみるとオンボードLEDが徐々に明るくなり、また徐々に暗くなることを繰り返します。
個人的備忘録：CloudFront で HTTPS を設定する方法と ACM 証明書 (us-east-1) の必要性についてまとめてみた

## はじめに

AWS CloudFront は、コンテンツを高速に配信するための **CDN (コンテンツデリバリーネットワーク)** サービスです。  

:::note info
**また、CloudFront で HTTPS を利用する場合は証明書が必要になりますが、その管理には **AWS Certificate Manager (ACM)** を利用するのが推奨されています。**
:::

本記事では、**CloudFront の基本概要と、HTTPS を有効にするための ACM 証明書の利用方法** について詳しく解説します。

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

CloudFront を利用してウェブサイトや API を運用する際、**「独自ドメインで HTTPS を有効化する方法」** について迷うことがありました。  

:::note warn
***特に、**ACM の証明書をどのリージョンで発行すべきか (`us-east-1` 限定)** という点は、初めて設定する際に引っかかりやすいポイントです。***
:::

このような **CloudFront と ACM の連携に関する重要なポイント** を整理し、スムーズに設定できるようまとめることにしました。


## CloudFront とは？

CloudFront は、AWS が提供する **CDN (コンテンツデリバリーネットワーク)** サービスです。  
世界中のエッジロケーションを利用して、ウェブサイトのコンテンツを高速に配信し、レイテンシを削減します。

- **キャッシュ機能** により、オリジンサーバーの負荷を軽減  
- **DDoS 対策** などのセキュリティ機能を提供  
- **S3, EC2, ALB** などと簡単に統合可能  
- **HTTPS 対応** により、安全な通信を確保  

CloudFront を活用することで、**ウェブアプリやストリーミング配信のパフォーマンスを向上** させることができます。  

## AWS Certificate Manager (ACM) とは？

AWS Certificate Manager (ACM) は、**SSL/TLS 証明書の発行・管理を自動化** する AWS のサービスです。

- **無料でパブリック証明書を発行可能**  
- **証明書の自動更新** により、運用負担を軽減  
- **CloudFront, ALB, API Gateway** などと簡単に統合  
- **手動での証明書インポートも可能**  

特に、**CloudFront で独自ドメイン + HTTPS を設定する場合、ACM の証明書 (`us-east-1`) を利用するのが推奨** されています。  

## CloudFront での証明書発行と利用に関するまとめ

### 1. ACM 証明書の利用が推奨される理由

CloudFront で HTTPS を利用する際、AWS Certificate Manager (ACM) の証明書が推奨されます。

- **無料で利用可能** → 追加コストなしで証明書を発行  
- **自動更新** → 証明書の有効期限管理が不要  
- **AWS サービスとの統合が容易** → CloudFront, ALB, API Gateway などと簡単に連携  

### 2. ACM 証明書のリージョン制限

CloudFront で ACM 証明書を利用する場合、証明書は **「米国東部 (バージニア北部) `us-east-1`」で発行またはインポート** する必要があります。

- **理由:**  
  - CloudFront はグローバルサービスのため、証明書を 1 つのリージョンに統一することで管理を簡素化  
  - **別のリージョンで発行した ACM 証明書は、CloudFront では適用不可**  

そのため、**CloudFront に HTTPS を設定する場合は、必ず `us-east-1` で ACM 証明書を発行** するようにしましょう。

## まとめ

- **CloudFront は AWS の CDN サービスであり、高速配信・セキュリティ強化に役立つ**  
- **HTTPS を有効にする場合、AWS Certificate Manager (ACM) の証明書を利用するのが推奨**  
- **CloudFront で ACM 証明書を利用する場合、必ず `us-east-1` (バージニア北部) で発行する必要がある**  
- **別のリージョンで発行した ACM 証明書は CloudFront では利用不可**  

CloudFront を使う際は、**セキュリティとパフォーマンスの向上を意識しつつ、ACM 証明書を適切に設定することが重要** です。  
本記事が、**CloudFront の HTTPS 設定で困っている方の助けになれば幸いです！**
ローカル環境で動作する次世代AIエージェント「Goose」のインストールガイド&使用感

# はじめに
GooseはオープンソースのAIエージェントです。
どのようなものかは既にまとめていただいている記事がありましたので、参照してください。

- [ローカル環境で動作する次世代AIエージェント「Goose」を解説](https://zenn.dev/aimasaou/articles/b5e831d200c2e2)
- [Rust製MCP対応AIエージェント『Goose』の技術概要](https://laiso.hatenablog.com/entry/2025/02/05/210854)

今回はGooseのインストールから試しに使ってみた部分までをまとめていきます。

## サポートされている環境
Goose CLIはmacOSおよびLinuxシステム対応でWindowsでもWSLを通じて実行できます。
デスクトップアプリはmacOSでのみ利用可能です。


## macでのインストール手順

### Goose CLI のインストール

1. **ターミナルを使用して次のコマンドを実行します：**
   ```
   curl -fsSL https://github.com/block/goose/releases/download/stable/download_cli.sh | bash
   ```
   このスクリプトは最新バージョンの Goose を取得し、システムにセットアップします。

2. **オプション設定**
   - インタラクティブな設定をスキップするには、次のコマンドを実行します：
     ```
     curl -fsSL https://github.com/block/goose/releases/download/stable/download_cli.sh | CONFIGURE=false bash
     ```

3. **インストール確認:**
   以下のコマンドで Goose が正しくインストールされたか確認します。
   ```
   goose session
   ```

### Goose Desktop のインストール

1. **Goose Desktop をダウンロードします：**
   [こちらのリンク](https://github.com/block/goose/releases/download/stable/Goose.zip)から Goose Desktop の最新バージョンをダウンロードします

2. **ファイルを展開します：**
   ダウンロードした `Goose.zip` ファイルを解凍します

3. **アプリを起動します：**
   解凍したフォルダ内にある実行可能ファイルをダブルクリックして Goose Desktop アプリを起動します。

## macで両方インストールした結果
- 初期設定はCLIインストール時にProvider設定を実施しました
- PATHの追加は自動ではないので、自分で追加しました
- デスクトップアプリは起動しましたが、Provider設定画面が表示されず、CLIで設定したProviderが使用されました
- デスクトップ側でExtensionsのComputer Controller, Memoryを有効化して、goose configureを確認するとExtensionsは共有されていませんでした
- 入力は日本語も入力できるのですが、Enter押すと反応してしまうので、他のテキストエディタかなにかで書いてコピーするという一手間が必要でした

## 使用感
- macでデスクトップアプリを使用して、この記事のドラフトを書いてもらいました
  - URLを投げて、インストールガイドを参照しながらインストール部分を書いてもらえました
  ![goose_desktop.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479886/c3aafe16-1bb4-4651-0fd2-9578da9afc27.png)

- 今回はデスクトップアプリを使用しましたが、CLIであればプログラミングとも組み合わせらせるので、より便利になると思いました。

# 最後に
- Goose は、オープンソースのAIエージェント
- 初回インストール後、必要な API プロバイダー設定を行えば、すぐに使用を開始できます
- CLI と Desktop のどちらも利用可能であり、用途に応じて柔軟に選択できます

# その他のリソース
- [公式リンク](https://block.github.io/goose/docs/getting-started/installation)
- [ローカル環境で動作する次世代AIエージェント「Goose」を解説](https://zenn.dev/aimasaou/articles/b5e831d200c2e2)
- [Rust製MCP対応AIエージェント『Goose』の技術概要](https://laiso.hatenablog.com/entry/2025/02/05/210854)
PMBOK原理・原則 : 価値の重視

サブタイトル：プロジェクトの成果がもたらす価値を継続的に評価し、調整する
PMBOKの「価値の重視」について解説記事を書きました📘
プロジェクトの成功は、単なる成果物の完成ではありません。本当に価値のある成果を生み出せているか、継続的に評価し改善することが大切です。ポイントをまとめています。ご参考になれば幸いです🙏

![マインドマップ (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/0ce6bd79-520f-0221-9292-7d261d77e897.png)

## はじめに
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/37e152f5-eb17-1349-5d92-349ea13c6fa0.png)

こんにちは。今回は PMBOK（Project Management Body of Knowledge）の原理・原則のうち「**価値の重視**」をテーマにご紹介します。

PMBOK と聞くと堅苦しいイメージを持たれる方も多いと思いますが、なるべく読みやすさを意識してまとめました。

## 1. 価値の重視とは？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/bd08b1b7-d705-348c-6004-d7b8f5a478ee.png)

- **プロジェクトを通じて生み出される“価値”を常に意識し、状況に応じて調整を行うこと**。
- 成果物の完成だけにフォーカスするのではなく、**誰に・どのようなメリット**を提供できるのかをしっかり意識する。

例えば「納期通りにリリースできたが、想定していたユーザーが使いこなせず、結局別のシステムで代用された」という状況は、**プロジェクトとしての価値を最大化できていない**と言えます。

## 2. なぜ価値を重視する必要があるのか？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/136cf7fc-e5b0-8935-4720-1bc75955bbf3.png)

### 1. 顧客満足度の向上
- ユーザーの課題やニーズを満たすことが大前提。
- 「本当に役に立つ！」と感じてもらえて初めて価値が生まれる。

### 2. 経営資源の有効活用
- 限りあるリソースを価値のない成果物に使うのは避けるべき。

### 3. プロジェクトの方向修正がしやすい
- 定期的に評価することで早期に問題を発見し、軌道修正が可能。

## 3. 具体的な実践方法

### 3.1. 目的・目標の明確化
- プロジェクトの目的を関係者全員が理解する。
- 例：「売上10%アップ」「問い合わせ対応コスト30%削減」など。

### 3.2. ステークホルダーとの定期的なコミュニケーション
- フィードバックを基に小さな単位で修正を重ねる。

### 3.3. 定量/定性の両面から価値を評価
- **KPI（Key Performance Indicators）**を設定。
- **ユーザーテストやインタビュー**を実施し、定性的な意見も収集。

### 3.4. アジャイルなアプローチの活用
- スプリントごとに小さな成果物を作成し、フィードバックを得る。

### 3.5. プロセスの見直しを柔軟に行う
- 価値が得られていない場合はプロセスや計画を見直す。

## 4. 注意したいポイント

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/354ac458-b945-12ad-1023-932c278d21fc.png)

### 4.1. 過度な変更要求への対処
- 変更の効果とコストを整理し、優先順位を明確に。

### 4.2. 間違った成功指標にとらわれない
- KPI達成だけでなく、**本来の価値提供**を意識する。

### 4.3. チームの合意形成
- 「価値」を重視する施策は、チーム全員の共通認識が重要。

## 5. まとめ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/0f8ceafe-6c3a-e98e-6363-61e57118aaa6.png)

- **価値の重視**とは、成果が本当に「役に立つものになっているか」を継続的にチェックし、調整すること。
- 目的設定、定期的なフィードバック、KPIモニタリング、アジャイル的な進め方が重要。
- 状況に応じてプロセスをアップデートすることで、プロジェクトの価値を最大化できる。
#0036（2024/02/06）アプリケーションのエラーケース

# アプリケーション開発におけるテストのエラーケース

アプリケーション開発では、システムが予期しない異常な状況下でも正しく動作するかを確認するために、さまざまなエラーケースを想定したテストが必要です。  
ここでは、代表的なエラーケースと、そのテスト時に確認すべきポイントについて解説します。  

---

## 1. パラメータ異常

**概要:**  
ユーザーや他システムから受け取る入力パラメータが、意図しない値や形式になっている場合の動作を検証します。

**主なケース:**  
- **不正なデータ型:** 期待される型（例：整数、文字列）とは異なる型の値が渡される場合。  
- **範囲外の値:** 数値が許容範囲を超えている、または文字列の長さが制限を超える場合。  
- **必須パラメータの欠如:** 入力に必須の項目が欠けている場合。  
- **フォーマット不正:** メールアドレス、日付、電話番号など、特定のフォーマットが必要なパラメータが不正な形式の場合。

**テストのポイント:**  
- 入力検証が適切に実施され、異常値の場合にエラーメッセージが返されるか。  
- システムが安全にエラーをハンドルし、クラッシュや予期しない動作が起こらないか。

---

## 2. HW異常

**概要:**  
システムが依存するハードウェアの異常（ディスク、メモリ、ネットワークなど）に対して、アプリケーションがどのように対処するかを確認します。

**主なケース:**  
- **ディスク障害:** 読み書きエラーやディスク容量の枯渇。  
- **メモリ不足:** システムメモリの枯渇によるパフォーマンス低下やクラッシュ。  
- **ネットワーク障害:** 接続の切断、パケットロス、遅延などによる通信エラー。  
- **周辺機器の不具合:** センサーやその他の外部デバイスの故障。

**テストのポイント:**  
- ハードウェア障害時のエラーハンドリング、リトライ処理、フェイルオーバーが適切に行われるか。  
- 障害発生時に適切なログ記録や通知が行われ、迅速に対応できる体制が整っているか。

---

## 3. プロセス異常

**概要:**  
システム内のプロセスが異常終了、ハング、または予期しない動作を起こした場合の対処方法を検証します。

**主なケース:**  
- **プロセスクラッシュ:** 例外発生やシグナル受信による突然の終了。  
- **タイムアウト:** 外部プロセスとの通信がタイムアウトし、結果が得られない場合。  
- **リソースリーク:** メモリ、ファイルディスクリプタ、接続などのリソースが解放されない場合。

**テストのポイント:**  
- 異常終了時にシステム全体に影響が及ばないように、適切なリカバリや再起動の仕組みがあるか。  
- 障害発生時のログ記録とアラート機能が適切に機能しているか。

---

## 4. 不正なシーケンス

**概要:**  
アプリケーション内の処理や、システム間のトランザクションが、想定された順序で実行されない場合の影響を検証します。

**主なケース:**  
- **操作順序の誤り:** たとえば、ログイン前に特定の操作を実行しようとする場合。  
- **非同期処理の競合:** 非同期タスクが実行順序の乱れによりデータ不整合やデッドロックを引き起こす場合。  
- **トランザクションの不整合:** コミットやロールバックが適切なタイミングで行われない場合。

**テストのポイント:**  
- シーケンス違反が発生した場合、適切なエラー処理とシステムの状態保全が行われるか。  
- 状態遷移の検証や、順序が乱れた際のリカバリメカニズムが実装されているか。

---

## 5. セキュリティ

**概要:**  
システムが攻撃や不正アクセスに対してどのように防御できるか、または異常な入力や動作に対してどのように反応するかを検証します。

**主なケース:**  
- **認証・認可の失敗:** 不正なユーザーや権限外の操作が行われた場合。  
- **インジェクション攻撃:** SQL インジェクション、クロスサイトスクリプティング（XSS）などの攻撃。  
- **セッション管理の問題:** セッションハイジャックや不正なセッション継続。  
- **暗号化の不備:** データ送受信や保管時の暗号化が不十分な場合。

**テストのポイント:**  
- 脆弱性スキャンやペネトレーションテストにより、セキュリティホールがないか確認する。  
- エラー発生時に内部情報が漏洩しないよう、エラーメッセージが適切に制限されているか。

---


## 6. ネットワーク異常

**概要:**  
通信環境の不安定さ、遅延、切断など、ネットワークに起因するエラーケースです。

**テストのポイント:**  
- ネットワーク障害時の再接続、リトライ、タイムアウト処理が適切に行われるか。  
- 通信エラー発生時にシステム全体が影響を受けず、部分的な機能停止で済むか。

---

## 7. パフォーマンス異常

**概要:**  
高負荷やリソース枯渇状態で、システムが適切に動作するかを確認します。

**テストのポイント:**  
- ストレステストや負荷テストにより、システムのボトルネックやパフォーマンス低下の原因を特定する。  
- 異常時のエラーハンドリングやリソースの解放が適切に行われるかを検証する。

---

## まとめ

エラーケースのテストは、システムの堅牢性と信頼性を保証するために不可欠です。  
各エラーケースごとに、以下の点を重点的に確認しましょう。

- **パラメータ異常:** 入力値の検証と適切なエラーハンドリング。  
- **HW異常:** ハードウェア障害時のリカバリ機能と監視体制。  
- **プロセス異常:** 異常終了やリソースリークに対する自動再起動やログ記録。  
- **不正なシーケンス:** 操作順序の乱れに対する防御と状態管理。  
- **セキュリティ:** 認証、入力検証、暗号化、セッション管理の徹底。  
- **ネットワーク異常・パフォーマンス異常:** それぞれの障害に対するリトライ、タイムアウト、負荷分散の実装。
#0035（2024/02/04）RTSP 接続のカメラ映像取得の確認方法

# RTSP 接続のカメラ映像取得の確認方法

このドキュメントでは、RTSP 接続のカメラ映像取得に関して、以下の3つの確認方法について説明します。

1. **コマンドで接続を確認する方法**
2. **サードパーティツール（例：VLC）を使って接続を確認する方法**
3. **Python と OpenCV を使ってキャプチャを取得し可視化する方法（最低限のコード例）**

---

## 1. コマンドで接続を確認する方法

RTSP ストリームに直接接続して、映像が取得できるかをコマンドラインで確認できます。  
ここでは `ffplay` と `ffprobe` の2つのツールを利用した方法を紹介します。

### ffplay を使う方法

`ffplay` は、FFmpeg の付属ツールで、RTSP ストリームを再生するために使用できます。

```bash
ffplay rtsp://{username}:{password}@{camera_ip}:{port}/{path}

- username: カメラのユーザー名
- password: カメラのパスワード
- camera_ip: カメラの IP アドレス
- port: RTSP ポート（通常は 554）
- path: カメラが提供するストリームのパス
```

ffprobe を使う方法

ffprobe は、ストリームの情報や接続状況を確認するために使用されます。

``` bash
ffprobe rtsp://username:password@camera_ip:port/path
```

これにより、ストリームの詳細情報（解像度、フレームレート、コーデック情報など）や接続状況を確認することができます。

## 2. サードパーティツールを使って接続を確認する方法

VLC メディアプレイヤーでの確認

VLC メディアプレイヤーは、RTSP ストリームの再生確認に非常に便利なツールです。
以下の手順で接続を確認できます。
1.	VLC を起動
    - VLC メディアプレイヤーを開きます。
2.	ネットワークストリームを開く
    - メニューから「メディア」→「ネットワークストリームを開く」を選択します。
3.	RTSP URL を入力
    - 次の形式の URL を入力します: `rtsp://{username}:{password}@{camera_ip}:{port}/{path}`

4.	再生開始
    - 「再生」ボタンをクリックすると、カメラの映像が再生され、接続が正常かどうかを確認できます。


## 3. Python と OpenCV を使ってキャプチャを取得し可視化する方法

以下は、Python と OpenCV を使用して RTSP ストリームから映像をキャプチャし、ウィンドウに表示する最低限のコード例です。

``` python
import cv2

# RTSP URL を設定（各パラメータを適宜置き換えてください）
rtsp_url = "rtsp://{username}:{password}@{camera_ip}"

# VideoCapture オブジェクトを作成してストリームに接続
cap = cv2.VideoCapture(rtsp_url)

# 接続確認
if not cap.isOpened():
    print("RTSP ストリームに接続できませんでした。")
    exit()

while True:
    ret, frame = cap.read()
    if not ret:
        print("フレームの取得に失敗しました。")
        break

    # フレームの表示
    cv2.imshow("RTSP Stream", frame)

    # 'q' キーが押されたらループ終了
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# リソースの解放とウィンドウの破棄
cap.release()
cv2.destroyAllWindows()
```

コードのポイント
	•	接続確認: cap.isOpened() で RTSP ストリームへの接続が確立できたかをチェックします。
	•	フレーム取得: cap.read() により映像フレームを逐次取得します。
	•	映像表示: cv2.imshow() を使用してリアルタイムに映像を表示します。
	•	終了条件: キー入力（‘q’）でループを抜け、プログラムを終了します。
【Python】pydanticのStrictBoolとは？boolとの違いは何？

# 概要
pydanticの`StrictBool`を使用してみました。
より厳格に型チェックを行いたいときはこちらの利用が推奨されています。
と言うこｔ実際に検証！

### pydanticのStrictBoolとは？
pydanticのドキュメントには以下のように記載があります。

> StrictBool module-attribute
StrictBool = Annotated[bool, Strict()]
A boolean that must be either True or False.
https://docs.pydantic.dev/2.2/api/types/#pydantic.types.StrictBool

必ず`True`から`False`である必要がある、と。

では普通の`bool`と何が違うのか？

私が実際に検証した限り、`1`や`0`はそれぞれTrueやFalseに変換されない、と言う点が大きな違いと思います。

以下、相違点です。

### `bool`を利用する場合
- TrueとFalseを受け入れる
- 以下の値も受け入れ、`True`または`False`に変換する
    - `1`や`0`
    - `"1"`や`"0"`
    - `"true"`や`"false"` 

### pydanticの`StrictBool`
- TrueとFalseを受け入れる
- 以下の値は受け入れない
    - `1`や`0`
    - `"1"`や`"0"`
    - `"true"`や`"false"

ちなみに例えばpydanticの`StrictBool`の項目に対して「`1`」を連携すると、

> `Input should be a valid boolean`

と言うバリデーションエラーになりました。
厳格なチェックが行われていることが分かりました。

以上、それぞれの違いをまとめました。
AngularFire とFirebase Emulator Suite で詰まった話

## 前置き
これまでは、とりあえずFirebase 上で動かしたいという思いでEmulator を使用していなかった。  
一旦Firebase 上にAngular アプリをデプロイできたので、ちゃんと環境を整えようとして詰まった。  
この記事はその時に調べたことをまとめたものです。  

## 本編
とりあえず、storage については以下のように修正すれば動く。  
```
export const appConfig: ApplicationConfig = {
  providers: [
    provideZoneChangeDetection({ eventCoalescing: true }),
    provideRouter(
      routes,
      withInMemoryScrolling({
        anchorScrolling: 'enabled',
      }),
    ),
    provideHttpClient(),
    provideAnimationsAsync(),
    provideFirebaseApp(() => initializeApp(FIREBASECONFIG)),
    provideAnalytics(() => getAnalytics()),
    ScreenTrackingService,
    // provideStorage(() => getStorage()), 
    provideStorage(() => {
      const storage = getStorage();
      connectStorageEmulator(storage, 'localhost', 9199);
      return storage;
    }),
  ],
};
```
見ればわかるけど、`connectStorageEmulator`でEmulator のホスト・ポートを設定する。  
他はまだやっていないけど、`connectAuthEmulator`等あるので、似た感じで行けると思う。  
ただ、これだけだと必ずEmulator に行くので、フラグ管理等は必要。  


## おまけ
ここからは僕用のメモというかそんな感じの。  

最初にやったことはemulator の使用例を探した。  
けど、compat(後方互換用のやつ)以外に記載がなかった。  
この記載によると、`USE_EMULATOR`というInjectionToken を注入していた。  
なんでもStorage オブジェクトに`useEmulator()`メソッドがあり、それを使っているらしい。  
一応、直接呼ぶことも出来はする。  
ただし、compat は後方互換用のものなので、必要でなければ使わない方が良いらしい。  

一方で、普通(compat でない)のやつのソースを見てもそれっぽいものを見つけられなかった。  
困ったので、ChatGPT に聞いてみたら、↑の`connectStorageEmulator`を使うやり方を教えてくれた。  
これはFirebase JavaScript SDK を再エクスポートしていた。  
こちらのソースを確認すると、Storage の型が二種類(`FirebaseStorage`,`FirebaseStorageImpl`)あることが分かった。  
加えて、通常触るのは`FirebaseStorage`だが、実態は`FirebaseStorageImpl`であり、`host`を含むいくつものプロパティが隠蔽されていることが分かった。  
`connectStorageEmulator`を実行すると、`host`を指定したオーソリティに書き換え(他にもスキーム等も変えるっぽい)、Emulator へリクエストを送るらしい。  
一応、Storage オブジェクトを`console.log`で出力したら、確かに`_host`プロパティがあった。  

ChatGPT 先生ありがとう！

一旦Emulator への切り替えができたので、落ち着いた気持ちで他に方法がないかソースを見た。  
すると、`getStorage()`で`getDefaultEmulatorHostnameAndPort()`を実行していた。  
ここでは、グローバル変数(ブラウザのwindow等)、環境変数、cookie を参照し、対応した値があれば適用していた。  
なので、`connectStorageEmulator`を使わなくても切り替えは可能ではあった。  
しかし、今回は`connectStorageEmulator`を使った方がやりやすいと思ったので、使わない。  

あと、Emulator に初期データを読み込ませる方法について、一応自分で作成することも出来なくはないはず。  
一応試したけど、思ったより大変だったので、`--import=./data --export-on-exit`オプションを追加した。  
これで、最初にUI 上の操作が必要だが、移行は不要になる。  


## 感想
楽しかった。  


今回の記事は以上です。  

前回記事はこちら  

https://qiita.com/magurouhiru/items/3749a2b565b7d99be852

詳細見たい人はこちら  

https://mysite-with-firebase.firebaseapp.com/
rex0220 計算式プラグイン 項目が変更されたか表示

[計算式プラグイン](https://qiita.com/rex0220/items/ae83c6d5ce50ff7a9a73)で、項目が変更されたかの表示を行ってみます。

# 概要

日付・文字列・数値、チェックボックスなどが変更された場合に、表示してみます。
編集画面表示に変更チェックをリセットして、表示します。

- 日付変更チェック

![2025-02-06_21h01_14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/ed52736b-f436-ea17-d195-acd0849da2f1.png)

- 日付・文字列・数値、チェックボックス変更チェック
    - 文字列複数行に変更項目をまとめて表示

![2025-02-06_21h02_29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/5014e20f-baff-42af-ccf2-bbdca599f8d2.png)


# 日付変更チェック

スペース項目に日付変更メッセージを表示します。

## アプリ設定

日付項目のチェック用に、それぞれ日付項目とチェック表示用スペースを配置します。

- 日付1: 日付1A, sp1
- 日付2: 日付2A, sp2

![2025-02-06_21h10_27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/55d00a0c-cb53-dd81-9a90-7cd54c0e9282.png)

## プラグイン設定

日付1A、日付2A は、編集画面表示時に最初に計算処理を行わせるため、ランクに「1」をセットします。

![2025-02-06_21h08_41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/fcaaa189-34fd-bdd4-1c5f-25353b23a93d.png)

```.js
OPTION: 循環参照を許可

// 日付1A DATE (hide, rank:1)
IF(
  OR(EV_INFO("cate")="create",
    IN(EV_INFO("type"),
    "app.record.edit.show","mobile.app.record.edit.show")),
  日付1,日付1A
)

// sp1:(sp1) SPACER
IF(日付1!=日付1A,"日付1が更新されました")

// 日付2A DATE (hide, rank:1)
IF(
  OR(EV_INFO("cate")="create",
    IN(EV_INFO("type"),
    "app.record.edit.show","mobile.app.record.edit.show")),
  日付2,日付2A
)

// sp2:(sp2) SPACER
IF(日付2!=日付2A,"日付2が更新されました")
```

# 日付・文字列・数値、チェックボックス変更チェック

変更チェックする項目が多い場合は、各項目の値をまとめて保持します。
こちらでは、チェック表示用に文字列項目と文字列複数行を利用します。
配列で選択肢を持っているチェックボックスは、JOIN 関数で文字列に変換して比較します。

## アプリ設定

各項目のチェック表示用文字列項目を配置します。
また各項目の値をまとめて保持する「更新チェック用」を配置します。

![2025-02-06_21h16_59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/f984b499-b3e4-25e7-e893-4dce1a6b1918.png)


## プラグイン設定

![2025-02-06_21h15_49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/9f197039-8e42-fb7b-7e19-2f7bed1ce3c2.png)

```.js
OPTION: 循環参照を許可

// 日付1チェック SINGLE_LINE_TEXT
LET(dic,JSON_P(更新チェック用),
  IF(DIC_ITEM(dic,"日付1")!=日付1,"日付1が更新されました")
)

// 日付2チェック SINGLE_LINE_TEXT
LET(dic,JSON_P(更新チェック用),
  IF(DIC_ITEM(dic,"日付2")!=日付2,"日付2が更新されました")
)

// 文字列1チェック SINGLE_LINE_TEXT
LET(dic,JSON_P(更新チェック用),
  IF(DIC_ITEM(dic,"文字列1")!=文字列1,"文字列1が更新されました")
)

// 数値1チェック SINGLE_LINE_TEXT
LET(dic,JSON_P(更新チェック用),
  IF(DIC_ITEM(dic,"数値1")!=数値1,"数値1が更新されました")
)

// チェックボックス1チェック SINGLE_LINE_TEXT
LET(dic,JSON_P(更新チェック用),
  IF(DIC_ITEM(dic,"チェックボックス1")!=JOIN(チェックボックス1,","),"チェックボックス1が更新されました")
)

// 更新項目 MULTI_LINE_TEXT
LET(
  old,JSON_P(更新チェック用),
  new, DIC(
     "日付1",日付1,
     "日付2",日付2,
     "文字列1",文字列1,
     "数値1",数値1,
     "チェックボックス1",JOIN(チェックボックス1,",")
  ),
  arr, DIC_MAP(old, key, val, 
     IF(DIC_ITEM(new,key)!=val,
       "・"&key&"が更新されました"
     )
  ),
  JOIN(arr, NEWLINE(), 1)
)

// 更新チェック用 SINGLE_LINE_TEXT (rank:1)
IF(
  OR(EV_INFO("cate")="create",
    IN(EV_INFO("type"),
    "app.record.edit.show","mobile.app.record.edit.show")),
  JSON_S(DIC(
     "日付1",日付1,
     "日付2",日付2,
     "文字列1",文字列1,
     "数値1",数値1,
     "チェックボックス1",JOIN(チェックボックス1,",")
   )),
  更新チェック用
)
```
Ant Design の DatePicker をカスタムして、フォーカスアウトで指定したフォーマットに変換する方法

## はじめに

[Ant Design](https://ant.design/) は、React用の UIフレームワークの一つで、洗練されたデザインと豊富なコンポーネントが特徴だが、あまり日本語の記事がない。
その中でも `DatePicker` は、日付を選択するためのコンポーネントになる。
ラップしたカスタム部品を作成する機会があったのでメモ書きとして残しておく。



## Ant Design の DatePicker とは？

`DatePicker` は、カレンダー UI を提供し、ユーザーが日付を選択できるようにするコンポーネントで以下のように簡単に導入できる。

```tsx
import React, { useState } from 'react';
import { DatePicker } from 'antd';
import dayjs, { Dayjs } from 'dayjs';

const BasicDatePicker: React.FC = () => {
  const [date, setDate] = useState<Dayjs | null>(null);

  return <DatePicker value={date} onChange={setDate} format="YYYY/MM/DD" />;
};

export default BasicDatePicker;
```

しかし、 `YYYYMMDD` 形式で入力された日付がフォーカスアウトされたタイミングで
`YYYY/MM/DD` 形式に変換する必要があり `DatePicker` をラップした `CustomDatePicker` 部品を作成した。



## 実装

### `CustomDatePicker` の要件

- `YYYYMMDD` の入力を受け付ける
- ユーザーがフォーカスアウトした際にフォーマットを適用
- デフォルトのフォーマットは `YYYY/MM/DD`
- カレンダー選択時はそのまま反映
- 無効な日付入力は `null` をセット

### 実装コード

以下のコードは `CustomDatePicker` の実装です。

```tsx
import React from 'react';
import { DatePicker } from 'antd';
import dayjs, { Dayjs } from 'dayjs';

// DatePicker のプロパティを定義
export interface CustomDatePickerProps {
  value?: Dayjs | null; // 選択された日付（null 許容）
  onChange?: (date: Dayjs | null) => void; // 値の変更時に呼ばれるコールバック関数
  placeholder?: string; // プレースホルダー
  format?: string; // 日付のフォーマット
  disabled?: boolean; // 無効化フラグ
}

// Ant Design の DatePicker をカスタマイズしたコンポーネント
const CustomDatePicker: React.FC<CustomDatePickerProps> = ({
  value,
  onChange,
  placeholder = '日付の入力・選択をしてください', // デフォルトのプレースホルダー
  format = 'YYYY/MM/DD', // デフォルトのフォーマット
  disabled = false, // デフォルトで有効
}) => {
  
  // カレンダーで日付を選択したときに実行
  const handleChange = (date: Dayjs | null) => {
    onChange?.(date); // 選択した日付を親コンポーネントに渡す
  };

  // フォーカスアウト時に入力値を検証・変換する処理
  const handleBlur = (e: React.FocusEvent<HTMLElement>) => {
    if (!(e.target instanceof HTMLInputElement)) return; // 入力フィールドでない場合は処理しない
    if (!onChange) return; // onChange が渡されていない場合は処理しない

    const inputValue = e.target.value.trim(); // ユーザー入力を取得し、前後の空白を削除

    // YYYYMMDD（例: 20240131）形式で入力された場合
    if (/^\d{8}$/.test(inputValue)) {
      const formattedDate = dayjs(inputValue, 'YYYYMMDD').format(format); // 指定フォーマットへ変換
      onChange(dayjs(formattedDate, format));
    } 
    // ユーザーが指定フォーマット (YYYY/MM/DD など) で入力した場合
    else if (dayjs(inputValue, format, true).isValid()) {
      onChange(dayjs(inputValue, format));
    } 
    // 無効な日付の場合
    else {
      onChange(null); // 無効な値は null を設定
    }
  };

  return (
    <DatePicker
      value={value} // 選択された日付
      format={format} // フォーマットを適用
      inputReadOnly={false} // 手動入力を許可
      placeholder={placeholder} // プレースホルダーの表示
      onBlur={handleBlur} // フォーカスアウト時の処理
      onChange={handleChange} // 日付選択時の処理
      disabled={disabled} // 無効化の設定
    />
  );
};

export default CustomDatePicker;

```

### `CustomDatePicker` の動作確認

1. `YYYYMMDD` 形式で入力すると、自動で `YYYY/MM/DD` にフォーマットされる
2. 無効な日付を入力すると `null` になる（画面上は非表示）
3. `DatePicker` のカレンダー UI から選択すると、そのまま値がセットされる



理想は、Ant Design の仕様をそのまま利用する要件にすることがいいと思うのですが、
そうもいかないのがシステム開発・・・
Flutterやってるとversion設定で大混乱

# 各プラットフォームのバージョン管理パラメータ一覧

| **項目**                   | **対象**         | **用途**                                     | **例**     |
|---------------------------|----------------|----------------------------------|-----------|
| `FLUTTER_BUILD_NAME`      | Flutter        | **Flutter アプリのバージョン（ユーザー向け）** | `1.2.3`   |
| `FLUTTER_BUILD_NUMBER`    | Flutter        | **Flutter アプリのビルド番号（内部管理）** | `42`      |
| `MARKETING_VERSION`       | iOS (Xcode)    | **App Store に表示されるバージョン**  | `1.2.3`   |
| `CURRENT_PROJECT_VERSION` | iOS (Xcode)    | **内部ビルド番号（App Store 提出時に必要）** | `42`      |
| `CFBundleShortVersionString` | iOS (`Info.plist`) | **ユーザー向けバージョン（App Store 表示）** | `1.2.3`   |
| `CFBundleVersion`         | iOS (`Info.plist`) | **内部ビルド番号（App Store に提出ごとに増加）** | `42`      |
| `versionName`             | Android (`build.gradle`) | **Google Play に表示されるバージョン** | `1.2.3`   |
| `versionCode`             | Android (`build.gradle`) | **内部ビルド番号（Google Play 提出用）** | `42`      |
| `build-name`              | Flutter CLI    | **`FLUTTER_BUILD_NAME` に相当（ユーザー向けバージョン）** | `1.2.3`   |
| `build-number`            | Flutter CLI    | **`FLUTTER_BUILD_NUMBER` に相当（内部ビルド番号）** | `42`      |
Dockerについて

こんにちは。
今回はDocker紹介します。
最後まで見ていただけると嬉しいです。

# Dockerとは？

https://www.docker.com/ja-jp/

### Dockerの概要

Dockerは、アプリケーションの開発から本番環境での運用まで、一貫した環境を提供するためのコンテナ技術を利用したプラットフォームです。開発環境と本番環境の差異をなくし、システムの再現性を高めることで、デプロイやスケールの効率を向上させます。

### Dockerが解決する課題

開発環境と本番環境の違いによる「動作しない問題（It works on my machine問題）」を解決します。例えば、ある開発者がローカルで動作確認したアプリケーションが、本番環境や他の開発者のPCでエラーを起こすといった問題がよくあります。Dockerを使うことで、どこでも同じ環境を再現できるため、このような問題を解消できます。

### 仮想マシン（VM）との違い

Dockerは「コンテナ」を利用してアプリケーションを実行しますが、従来の仮想マシン（VM）と比べると以下のような違いがあります。

### Dockerを活用するメリット

① 開発環境の統一が簡単

Dockerでは、開発者ごとに異なる環境を統一できるため、**「このライブラリのバージョン違いで動かない」**といった問題をなくせます。

実際の活用例

チーム開発において、Docker Compose を使用すれば、バックエンド（RailsやDjango）とフロントエンド（ReactやVue）を含む環境を簡単に構築できます。

② 高速で軽量な環境構築

VMのようにOS全体を起動する必要がないため、コンテナは数秒で起動可能です。これにより、テスト環境の作成やCI/CDパイプラインの構築がスムーズになります。

実際の活用例

GitHub ActionsやJenkinsなどのCI/CDツールと連携し、開発・テスト・デプロイを自動化することが可能です。

③ どこでも同じ環境で動作

Dockerイメージを作成すれば、ローカル開発環境・本番環境・クラウド（AWS, GCP, Azure）どこでも同じ状態でアプリケーションを動作させることができます。

### 実際の活用例

「本番環境でだけ動かない」というトラブルを防ぐために、本番環境と同じDockerコンテナをローカルでも動作させることで、事前検証が可能になります。

# コンテナ技術の基礎知識
https://www.docker.com/ja-jp/resources/what-container/

### コンテナとは？

Dockerにおけるコンテナは、アプリケーションの実行に必要なファイルやライブラリをすべて含んだ、独立した仮想環境です。

コンテナ技術の特徴

軽量 → 仮想マシンのようにOSを含まないため、リソース消費が少ない

ポータブル → どこでも同じコンテナを実行可能

分離性 → 他のコンテナと独立して動作するため、環境を汚さない


### 実践的な活用方法

Dockerを使った開発フローの例

Dockerfile を作成し、アプリの環境を定義

docker build でイメージを作成

docker run でコンテナを起動

docker-compose を使用して、データベースなどを含む環境を構築

このように、Dockerを活用することで環境構築の手間を省き、どこでも同じ環境で開発が可能になります。


# まとめ

Dockerは軽量で移植性の高いコンテナ技術

開発環境と本番環境を統一し、トラブルを防ぐ

Docker Composeを活用すれば、複数のサービスを簡単に管理可能

CI/CDと組み合わせることで、自動テスト・デプロイがスムーズに

以上です！
最後まで見ていただきありがとうございました！
フォルダ直下のファイルを日付毎に仕分けるスクリプト

Windowsの端末であとで整理しようと思っていたスクリーンショットがフォルダ上に大量にたまってしまうことが私はよくあります。
これをいったんフォルダ分けして自分の中で何があったかわかるようにしたいと思ったので整理するためのスクリプトを作成しました。

※これを
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3990347/11575a07-15db-a373-cf39-89d2e8ac09e2.png">
※こうしたい(各日付フォルダに、各日に取得したスクリーンショットが含まれる)
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3990347/59403068-a146-ad8f-5f86-5a063efe8dd6.png">


# スクリプト本体
```MoveDateFolder.ps1
##########################################################
# フォルダ上のすべてのファイルを、更新日付事に選別しそれぞれのフォルダに移動する
# Usage: .\MoveDateFolder.ps1 <対象フォルダ>
# 2025/2/6
##########################################################

# 引数設定箇所
# $SourceDir: 対象ファイルのあるフォルダ.未指定の場合フォルダ
Param(
    $SourceDir=(Get-Location).Path
)

# 対象フォルダ上のすべてのファイルに対して処理を実行。
# 「-File」オプションを使用してディレクトリは除外する。
foreach ($f in Get-ChildItem -File ${SourceDir}){
    # 移動先フォルダを対象ファイルの更新日付にするため更新日付を取得
    $Directory=$f.LastWriteTime.ToString("yyyyMMdd")
    
    # ファイル名を取得
    $Filename=$f.Name
    
    # ファイルのフルパスを取得
    $FileFull=$f.Fullname
    
    # 移行先フォルダが存在しない場合だけ作成する。
    if (!(Test-Path ${SourceDir}\${Directory}) ){
        New-Item -Path ${SourceDir} -Name $Directory -ItemType "directory" > $null
    }
    write-output "move from $FileFull To ${SourceDir}\${Directory}\"
    
    # フォルダ移動
    move-item $FileFull ${SourceDir}\${Directory}\
}
```

### スクリプトの使い方と仕様
```Command
PS> .\MoveDateFolder.ps1 -SourceDir <対象フォルダ>
```
<font color="Red">対象フォルダ</font> : 対象ファイルが存在するフォルダを指定してください。未指定の場合はカレントディレクトリで動作します。

* 指定したフォルダ上のすべてのファイルを直下に作成した日付フォーマットのフォルダ(yyyymmdd)に各ファイルの最終更新日時を基準に移動します。
* 操作対象フォルダの確認が入ります。確認に「Y」と入力された場合のみファイルが移動されます。
* サブフォルダおよびサブフォルダ内のファイルに対しては操作は行われません。

### 動作確認
冒頭のファイルに適当なフォルダを加えてテスト
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3990347/7bd1516b-bb12-f4c3-184a-23312add1456.png">

実行
一回目は実行をキャンセルし、二回目は実行しました。
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3990347/b50f69bd-bd35-5c27-978c-8d46d9caded4.png">

一回目実行時は移動されず二回目の実行で移動されました。もともと存在したフォルダは触れられていません。
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3990347/16eb3715-2f74-9da6-46da-eee44b9d33eb.png">
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3990347/3c57c44b-e5fe-9e05-1bbc-eafed5524edc.png">
ごみ捨てリマインドメールをGASで送っている話

## 概要
我が家では、GASを使用して、ごみ捨てのリマインドメールを送信しています。
夜21~22時頃に私と妻宛に「明日のごみは燃やせるごみです。出して良いごみは○○です」みたいなメールが届くようになっています。これに気づいたら、翌日出すゴミの準備をするようにしています。
方法は単純で、Googleカレンダーにゴミの予定日を登録して、それを前日にリマインドしているだけです。ごみの日をすぐに忘れてしまう私にとっては、少し便利なシステムです。

## Googleカレンダーへの登録
Googleカレンダーを開いて、「他のカレンダー」の横のプラスマークをクリックしましょう。「新しいカレンダーを作成」をクリックして、「○○市ゴミカレンダー」などと名前を付けて保存しましょう。
![カレンダー2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619378/38890250-2365-9c38-2df2-78f08ae2ebe0.png)

あとは、このカレンダーに、お住まいの地域のごみ捨ての情報を登録してください。
ごみの予定を登録する際には、第n○曜日や、毎週○曜日といった登録の仕方ができるので、これを使います。
![カレンダー3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619378/625784f7-30fc-c7c7-5550-b71603b133f9.png)

説明欄には、出すゴミの種類を記入しましょう。
![カレンダー7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619378/5e8febe8-1608-2a8b-2eca-8a10b4c4b429.png)

これで登録が完了すると、以下のようになります。
![カレンダー1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619378/1da2446e-3126-db41-f67c-011c0fae1507.png)
これで準備は完了です。

## カレンダーIDの取得
プログラムにカレンダーを読み込ませるためにカレンダーIDを取得する必要があります。
先ほど作成したカレンダーの横の「…」をクリックし、「設定と共有」を選択します。
![カレンダー4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619378/1f176768-817c-abe4-fbe1-f5266baa4b8f.png)

「カレンダーの統合」をクリックすると、「カレンダーID」がありますので、これをどこかにキープしてください。
![カレンダー5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619378/2c8847bb-c291-e295-5bc5-0aff977a7031.png)

## GASのスクリプト
Googleドライブを開いて、スタンドアロン型でスクリプトを書きましょう。
![カレンダー6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619378/b4650a75-ae08-e54c-5ba3-382ae67075d6.png)

記入するスクリプトは以下の通りです。
```java:Garbage_disposal
function garbage_disposal() {
  // 対象のカレンダーID
  const calendarId = 'ここにカレンダーIDを入力';
  // カレンダーオブジェクト取得
  const calendar = CalendarApp.getCalendarById(calendarId);

  // 現在日時を取得
  const today = new Date();
  const tomorrow = new Date(today.getTime() + 24 * 60 * 60 * 1000); // 
  const tomorrow2 = Utilities.formatDate(tomorrow, "JST", "MM/dd");
  if(tomorrow2 =="01/01" || tomorrow2 == "01/02" || tomorrow2=="01/03"){
    return
  }

  // 指定日の予定オブジェクトの配列の０番目を取得
  const event = calendar.getEventsForDay(tomorrow)[0];
  if (event === undefined) {
    Logger.log("No events found.");
  }
  // 予定が1件以上の場合
  else {
    let title = event.getTitle();
    let body = event.getDescription()
    Logger.log(title);
    Logger.log(body);
    email(title, body);
  }
}

function email(title, body) {
  GmailApp.sendEmail("私のメールアドレス,妻のメールアドレス", "明日のごみは【" + title + "】です", "明日のごみは" + title + "です\n出して良いごみは\n" + body + "\nです。\n\n※このメールは自動送信です。");
}
```

## トリガー設定
このスクリプトを、毎日２２時頃に実行するように設定します。
GASのエディタ画面から、目覚まし時計のマークをクリックして、トリガー画面を開きます。
![カレンダー8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619378/ce45253d-ef4b-5aa4-f8a5-b28f0dc3eef3.png)

「トリガーを追加」をクリックして、以下のように設定して、保存をクリックします
![カレンダー9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619378/f8792a51-3526-873d-3515-2ce478bc5923.png)

これで毎日21~22時頃に、Googleカレンダーの内容が指定したメールアドレスに届くはずです！
この仕組みを応用して、もっと便利な何かを作れないか検討中です。
今週の学習記録（2025/1/26～2025/02/01）

## 🔍 学習内容
- **学習テーマ**: JavaScript, TypeScript
- **使用した教材**: CodeLesson, Qiita, YouTubeなど

## ✏️ 学んだこと
### 主なポイント
- DOM操作
- 型の概念（TypeScript）

## 💡 学び・反省点
### 学び
- 「e.preventDefault()」でデフォルトの処理を阻止する。
- any型：どんな方でもいれることができる。やむを得ない場合に使用する。
- タプル型：関数から複数の値を返したいときに配列に入れてまとめて返す配列。特定の型である必要はない。
- variadic Tuple Types：配列のスプレッド構文のように、タプル型に要素を透け加えた別のタプル型を作ることができる機能。
- Type Alias(型エイリアス )を利用することで型に別名をつけることができる。
- null型はnullかundefinedしか代入することができない。typeofで比較した場合は'object'が出力される。
- !をつけることで、型を示すことができる。（Javaでいうキャストみたいな感じ？）

### 反省点
- 1日の学習時間が少ない日が多かった。 
- 学習中も集中できていないことが多かった。


## 📆 次週の予定
### 目標
- TypeScriptの理解度を高める。
- Reactの学習に入る。
- 最低でも平日1時間、休日4時間を目処に学習できるように努める。

### 行動計画
- 通退勤時間も積極的に学習する。
- 学習前に5分程度の運動を挟む
- 休日だからといって気を緩めすぎない。

## 🏄‍♂️所感
　今週からTypeScriptの学習にはいることができました。Javaには（多分）ない概念が多く非常に興味深かったです。最初のインプットはQiitaで行っていましたが、読んでいるだけだと頭に入らないことが多かったので積極的にメモを取るべきだと思いました。  
　TypeScriptは学習範囲がそこまで多くないためReactの学習にも入れるように努めたいと思います。
後輩のためのFigma入門（Step8）-Material colorの導入-

# 後輩のためのFigmaの使い方

後輩のためにFigmaに関して書きました。

Step8は「マテリアルカラーを導入しよう」です。

## 導入方法

**Step1** 以下の部分をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3950744/0711567c-c70d-0e1a-99de-8fa17d19d6d1.png)

<br> <!-- 空行を追加 -->

**Step2** 以下の部分をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3950744/c526e027-4361-5c8e-10f4-8a07c06cc4db.png)

<br> <!-- 空行を追加 -->

**Step3** **「Material Thema Builder」** を検索し、クリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3950744/7bb50c92-0d1f-63bd-72c6-246d9c809c36.png)

<br> <!-- 空行を追加 -->

**Step4** 以下の部分をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3950744/dac7fc8c-04d7-d719-5d05-bff8468b529d.png)

<br> <!-- 空行を追加 -->

**Step5** 以下の部分をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3950744/49a1285b-2c65-1a11-a20c-d57d3c5169b1.png)

<br> <!-- 空行を追加 -->

**Step6** 下にスクロールします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3950744/9cf99116-6e16-ac6f-cb08-b3deb13964fa.png)

<br> <!-- 空行を追加 -->

**Step7** 以下の部分をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3950744/943aaeed-fbca-3f39-234a-d075ef6efe83.png)

<br> <!-- 空行を追加 -->

**Step8** 以下の部分で色を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3950744/fb90b164-1b49-b95c-afa7-ce192f9d81cd.png)

<br> <!-- 空行を追加 -->

**Step9** 以下の部分をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3950744/7e93e490-9f4e-5f5c-ac6e-4459098b1053.png)

<br> <!-- 空行を追加 -->

**Step10** 以下の部分をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3950744/f23d4622-369a-afd9-80a9-3a054abec6dc.png)

<br> <!-- 空行を追加 -->

**Step11** Updateが灰色になるまで待ちます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3950744/d3bef3c8-cd5f-c547-dbd2-fa000345229f.png)

<br> <!-- 空行を追加 -->

**Step12** もうタブを消して大丈夫です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3950744/12c6473c-083a-5b14-3012-ab752587b993.png)

<br> <!-- 空行を追加 -->

## 使い方

<br> <!-- 空行を追加 -->

**Step1** 以下の部分をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3950744/be3bb012-ce32-8e65-cbca-95905a29766c.png)

<br> <!-- 空行を追加 -->

**Step2** 以下の部分をから色を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3950744/cced315d-b099-b6f2-6e6f-dbc476381af7.png)


## 続き
今回は、色の詳細設定を解説しました。
次回はAuto Layoutについて解説しようと思います。
フロントとバックでサーバーを分離した時のマルチテナントのサブドメインの考え方の勘違い

## 何を勘違いしていたか？
tenant1・tenant2・tenant3と三つのテナントがあったとします。
下記フロントとバックにおける各テナントのドメイン分け。

---
構成例：
- フロント
    - tenant1.example.com
    - tenant2.example.com
    - tenant3.example.com
- バック
    - tenant1.example.com
    - tenant2.example.com
    - tenant3.example.com
---
このように、フロントとバックにどちらも同じサブドメインを設定する必要があると思っていました。
（リバースプロキシを使ってこのように設定することもある？）
こうじゃない。

## どうするのか？
フロントかバックどちらかだけテナント用のサブドメインとかにする。
下記が例？

---
構成例１：
- フロント
    - tenant1.example.com
    - tenant2.example.com
    - tenant3.example.com
- バック
    - api.example.com

構成例：
- フロント
    - app.example.com
- バック
    - tenant1.example.com
    - tenant2.example.com
    - tenant3.example.com
---

（自分用メモ）
Linuxとは？

## Linuxとは
世界中で使われているオープンソースのオペレーティングシステムで無料で誰でも使用することができる。  
[オープンソース](https://git.kernel.org/ "Linuxのオープンソース")がすべて公開されている。


## Linuxはあらゆる機器を支えている
スマートフォン（Android）やスーパーコンピューター、組み込み系（テレビなど）などもLinuxOSをベースにしている。  


## なぜLinuxを学ぶべきか？
- カスタマイズ可能で幅広い分野で役立つ
- 無料で利用可能
- インフラ分野でデファクトスタンダードである
- 開発コミュニティが活発である


## Linuxの歴史
1991年　リーナス・トーバルズによって開発。
当時はUNIXが有名だったが、非常に高価であったため、安価で使えるOSとして世界中に広まっていった。  
最初はコンピューターの専門家の間で使われていたが、徐々にデスクトップ向けのユーザー、企業向けのディストリビューションも登場した。  
LinuxもMacもUNIXが共通の祖先として存在するため、似通っている部分がある。


## 使用教材、参考サイトなど
- [初心者OK！Linux入門：実務で必須のLinuxの知識を網羅](https://www.udemy.com/course/ok-linux/?couponCode=KEEPLEARNING)

## 終わりに
何か誤り等あればコメントにて教えていただけると幸いです。
Macでファイルをデフォルトで開くアプリの設定方法を何回も忘れるので書く


前からよく忘れるので、一度自分で記事にすることにより、記憶の定着を図る。

1.設定したいファイルを右クリックし、**情報を見る**をクリックする。
![](https://raw.githubusercontent.com/dddomain/zenn-qiita/refs/heads/main/images/スクリーンショット%202025-02-05%2016.26.28.png)

2.**このアプリケーションで開く**から、設定したいアプリを選択する。
![](https://raw.githubusercontent.com/dddomain/zenn-qiita/refs/heads/main/images/スクリーンショット%202025-02-05%2016.27.20.png)

3.**全てを変更** をクリックする。
![](https://raw.githubusercontent.com/dddomain/zenn-qiita/refs/heads/main/images/スクリーンショット%202025-02-05%2016.27.31.png)

4.ポップアップの**続ける**ボタンをクリックすると､設定完了。
![](https://raw.githubusercontent.com/dddomain/zenn-qiita/refs/heads/main/images/スクリーンショット%202025-02-05%2016.27.52.png)
hyperliquidのヒストリカルohlcv取得方法

<!-- title: hyperliquidのヒストリカルohlcv取得方法 -->
<!-- tags: Python, Hyperliquid, Botter -->

# hyperliquid の ohlcv 取得コード

何やら最近海外の仮想通貨取引所(CEX)のアプリがダウンロードできなくなっているそうで、今後 DEX での Bot 取引を考えている方も多いのではないでしょうか。

こちらは、hyperliquid のヒストリカル ohlcv を取得するコードです。

## ライブラリの import:

```python
import os
import pandas as pd
from datetime import datetime, timezone, timedelta
from hyperliquid.info import Info
from hyperliquid.utils import constants
```

各自インストールしてください。

## インスタンスの作成：

```python
# Infoクラスのインスタンスを作成
info = Info(constants.MAINNET_API_URL, skip_ws=True)

# ユーザーの状態を取得
user_state = info.user_state("WalletAddress")
print(user_state)
```

WalletAddress の部分は、hyperliquid で使うウォレットのアドレスを入れてください。

## ohlcv を取得したい銘柄と時間足をリストで設定。後ほどループで回す

```python
# シンボルと時間枠の設定
symbolList = ['BTC', 'SOL']
intervalList = ['15m','1h']
```

何ヶ月分取得するか設定。どうやら、合計で 5000 個分ほどしか hyperliquid は保持していないようです。どうしても欲しい場合は lz4 データから集計するしかなさそう（めんどくさい）。

```python
# 現在の時刻を基準に開始時間と終了時間を設定
end_time = int(datetime.now(timezone.utc).timestamp() * 1000)  # 現在のUNIXタイムスタンプ（ミリ秒単位）
start_time = int((datetime.now(timezone.utc) - timedelta(days=90)).timestamp() * 1000)  # 現在から90日前
```

## ohlcv 取得のループ処理：

```python
for symbol in symbolList:
    for interval in intervalList:
        # ローソク足データを取得
        ohlcv_data = info.candles_snapshot(name=symbol, interval=interval, startTime=start_time, endTime=end_time)

        df = pd.DataFrame(ohlcv_data)
        df['timestamp'] = pd.to_datetime(df['t'], unit='ms', utc=True)
        df.drop(columns=['t', 'T', 's', 'i'], inplace=True)  # 不要な列を削除
        df.set_index('timestamp', inplace=True)
        df = df.reindex(columns=['o', 'h', 'l', 'c', 'v', 'n'])  # カラム順を指定
        df[['o', 'h', 'l', 'c', 'v']] = df[['o', 'h', 'l', 'c', 'v']].astype(float)
        df.rename(columns={
            'o': 'op',
            'h': 'hi',
            'l': 'lo',
            'c': 'cl',
            'v': 'volume',
            'n': 'numtrade'
        }, inplace=True)
        df = df.tz_convert('Asia/Tokyo')
        df = df.astype('float64')
        print(df)
```

以上です。csv 保存等のコードは追加してください。
【Paiza】Bクラス問題をCopilotに解かせて虚無る

## 帰ってきたぜっ！！
2025年のこの1年が自分の残り寿命だと思って生きると決めた者です。

### ~~なんとなく~~危機感からPaiza再開
昨日より少し強くなるためにPaizaを開きました。
そうしましたら、なんとも愉快そうなコンテンツがあ〜りませんか。
まんまと着手。

問題はこちらの「ギャングのアジト」（ピクセルアートの対称性検査プログラム）

https://ppg.paiza.jp/denno2088/challenges/denno2088_c_b_02https://ppg.paiza.jp/denno2088/challenges/denno2088_c_b_02


よくわからないのでとりあえずCopilotさんに問題文を投げて、ご回答をいただく。

### ミッションクリア
PythonとC++でコードを作成してもらい、無事に正解。さすがCopilotさん。

　（（（（（（（（（（(*ﾟ▽ﾟ*)）））））））））））

さあ、ここから私はどうしたら強くなれるのでしょうか。。。

とりあえず、皆様のBランクのWrite up記事でも眺めていこうかなと思います。

### せっかくなのでコードを置いておく
<details><summary>Python</summary>

```rb
def is_symmetric(pixel_art): 
    N = len(pixel_art)
    for i in range(N):
        for j in range(N // 2):
            if pixel_art[i][j] != pixel_art[i][N - j - 1]:
                return False
    return True

#入力例
N = int(input().strip())
pixel_art = []
for _ in range(N):
    row = list(map(int, input().strip().split()))
    pixel_art.append(row)

#判定
if is_symmetric(pixel_art):
    print("Yes")
else:
    print("No")
```
</details>

<details><summary>C++</summary>

```rb
#include <iostream>
#include <vector>
using namespace std;

bool is_symmetric(const vector<vector<int>>& pixel_art) {
    int N = pixel_art.size();
    for (int i = 0; i < N; ++i) {
        for (int j = 0; j < N / 2; ++j) {
            if (pixel_art[i][j] != pixel_art[i][N - j - 1]) {
                return false;
            }
        }
    }
    return true;
}

int main() {
    int N;
    cin >> N;
    vector<vector<int>> pixel_art(N, vector<int>(N));
    for (int i = 0; i < N; ++i) {
        for (int j = 0; j < N; ++j) {
            cin >> pixel_art[i][j];
        }
    }

    if (is_symmetric(pixel_art)) {
        cout << "Yes" << endl;
    } else {
        cout << "No" << endl;
    }

    return 0;
}
```
</details>


## 感動
（実際に他の方の記事を読んで追記）

どうやらこの手の問題は、自分で関数を作って利用するみたいだ！←
関数を構築する為に、アルゴリズムの知識が必要という訳ですね。

楽しくなってきたあ

> 参考記事

https://qiita.com/anonymously115/items/a2b95b8299bccccd7926
WordPressの記事を自動でXに投稿するプラグインを作ってみた


# WordPressの記事をXに自動投稿するプラグインを開発しました

## はじめに

ブログを書いた後、いちいちXに投稿するのが面倒...そんな経験はありませんか？
私も同じ悩みを持っていたので、WordPressの記事を自動的にX（旧Twitter）に投稿するプラグインを開発しました。

https://github.com/sorein-mio/auto-post-to-x

## 主な機能

- 新規投稿時の自動投稿
- 記事更新時の自動投稿（オプション）
- カスタマイズ可能な投稿テンプレート
- カスタムハッシュタグ機能
  - 投稿ごとの個別設定
  - デフォルトハッシュタグの設定
  - カテゴリーをハッシュタグとして使用可能
  - 最大ハッシュタグ数の制限設定
- 管理画面からの簡単設定
- テスト投稿機能

## 技術的な詳細

### 使用技術
- PHP 7.0以上
- WordPress 5.0以上
- X API (Twitter API v2)
- cURL PHP拡張

### プラグインの構成
WordPressで使用するためにはプラグインディレクトリ内に下記のReadmeを除いた構成でアップロードしてください

```plaintext
auto-post-to-x/
├──── includes/
│ └── TwitterAPIExchange.php # Twitter-API-PHP
├── wp-to-x-auto-post.php # プラグインのメインファイル
└── README.md
```

### 主要な実装ポイント

1. **フック処理**
```php
// 新規投稿時のフック
add_action('publish_post', 'post_to_x');
// 更新時のフック
add_action('post_updated', 'update_post_to_x', 10, 3);
```

2. **投稿テンプレート処理**

```php
function format_post_message($post) {
  $template = get_option('x_post_template');
  $message = str_replace(
    ['{title}', '{url}'],
    [$post->post_title, get_permalink($post)],
    $template
  );
  return $message;
}
```

3. **ハッシュタグ処理**
   
```php
function get_post_hashtags($post_id) {
  $custom_tags = get_post_meta($post_id, 'x_hashtags', true);
  $category_tags = get_category_hashtags($post_id);
  return array_merge(
    explode(',', $custom_tags),
    $category_tags
  );
}
```

## 開発で苦労した点

### 1. API制限への対応
X APIには1ヶ月あたり1,500ツイートという制限があります。これに対応するため、以下の機能を実装しました：

- 更新投稿の間隔制御
- 投稿失敗時のエラーハンドリング
- API制限のカウント機能

### 2. 文字数制限への対応
Xの投稿文字数制限（280文字）に対応するため：

- テンプレート文字数のバリデーション
- URLの自動短縮
- ハッシュタグの文字数考慮

### 3. 投稿の重複防止
短時間での同一内容の投稿を防ぐため：

- 前回の投稿時刻の記録
- 更新間隔のチェック
  - 更新間隔は設定変更可能です  
- 投稿内容のハッシュ値比較

## 今後の展望

1. **機能追加予定**
   - カスタム投稿タイプのサポート
   - 画像投稿機能
   - 投稿スケジュール機能
   - より柔軟な投稿テンプレート

2. **改善予定**
   - パフォーマンスの最適化
   - エラーハンドリングの強化
   - 多言語対応

## おわりに

このプラグインはGitHubで公開しています：
https://github.com/sorein-mio/auto-post-to-x

ぜひ使ってみてください！
また、改善点や機能追加の要望があればGitHubのIssueやプルリクエストをお待ちしています。

## 参考資料
- [WordPress Plugin Handbook](https://developer.wordpress.org/plugins/)
- [X API Documentation](https://developer.twitter.com/en/docs)
【Unity初心者】Unityでネットゲームを作りたい【18】Unityで正常、ビルドしてandroidで異常

https://qiita.com/ysyss5500/items/4aeb23639a8cf3d67376
### Unityで正常、ビルドしてandroidで異常
画面にモンスターの一覧表示をしている
ちなみに、いろんな画面で同じ画像データ、同じ表示スクリプトをコピペで使用

UnityではPlayfabからのデータ読み込みで、ちゃんと表示されてる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3979014/2d3739f2-6109-04c0-ab84-924423ec7464.png)

でもなぜかビルドして実機で確認するとモンスターのデータを表示しない

読込しないようにした前回のJsonファイルからの読み込みだと表示するけど、入替作業がうまくいかない
PlayFabからの読み込みがエラーなのかというとそうでもない（テキスト設置後、読み込みエラーの所にテキストにエラーと表示するようにした）
プレイヤー設定がおかしいのかといっぱい調べて色々試したが、何も変わらない...
１週間ほど色々試してなんかプログラムがごちゃごちゃしてきてしまった(-_-;)

既存のJsonファイルからの読み込み表示は出来る
だから
```
 GameObject HP = GameObject.Find("HP" + j);
 Text HP_text = HP.GetComponent<Text>();
 HP_text.text = playermons.pmon[j].HP;
```
これは間違ってないはず

もう何していいかわからず、ここで質問しようとスクリプトを書いたときに気が付く、そういえばJsonファイルからのデータでandroid端末（実機）でやった時に何もデータが入れ替わらなかったのを思い出した

で、あいかわらずPlayFabから読み込んだデータをJsonファイルに書き込んでる所を発見。使わないんだから削除して再度確認すると

やった！できた！Unityと同じ動きになったｗ

多分

Jsonファイルへの書き込みが出来なくて動作が止まっていたとの判断

```
    public void GetUserData()
    {
        var request = new GetUserDataRequest();
        PlayFabClientAPI.GetUserData(request, OnSuccess, OnError);

        void OnSuccess(GetUserDataResult result)
        {
            //Debug.Log("通常プレイヤーデータ読込成功");

            //Pdata playerdata = JsonUtility.FromJson<Pdata>(result.Data["PlayerData"].Value);
            StreamWriter sw3 = new StreamWriter("Assets/Resources/playerdata.json", false);
            sw3.WriteLine(result.Data["PlayerData"].Value);
            sw3.Flush();
            sw3.Close();
```
の
```
            StreamWriter sw3 = new StreamWriter("Assets/Resources/playerdata.json", false);
            sw3.WriteLine(result.Data["PlayerData"].Value);
            sw3.Flush();
            sw3.Close();
```
ここ
Jsonファイル探して書き込みなさいって文章
パスがandroidだと違うのかそもそも書き込みがダメなのか
これを削除したら通常起動しました（実機で

プレイヤー設定で多分これ実用出来るように設定できそうだが、どこいじっていいかわからんし（勉強しろ）使わないほうがちゃんと動くならと
Jsonファイルへの書き込みをすべて排除し、PlayFabのプレーヤーデータのみでのデータ管理とした

したら、ビルドして実機で正常になった
ホント長かった...教えてくれる人居たらすぐこれ乗り越えられただろーなーと思ったが、勉強なった

やっと次に進める

←前  [【Unity初心者】Unityでネットゲームを作りたい【17】パネル間でデータの引継ぎをしたい～どのボタンが押されてるか判断して次のパネルへ～Jsonファイルの読み込みが早すぎる？](https://qiita.com/ysyss5500/items/9be5fba0737d5f4ccd64)

[【Unity初心者】Unityでネットゲームを作りたい【19】少しだけPlayFabへの書き込みに時間がかかる気がする～PlayFabの仮想通貨に手を出す](https://qiita.com/ysyss5500/items/8259b7ee93a05ea21ecb)　次→

https://qiita.com/ysyss5500/items/4aeb23639a8cf3d67376
少しでも効率よく

# はじめに
要素有無を判定するときに、Countメソッドを使ってリストを要素数を数えて、0以上とか判定するより、Anyメソッドを使って要素有無判定する方が処理効率は良い
コードレビューで上記のコメントをいただいたため、内容を調べてみた

# コードサンプル
Countメソッドを使う場合
```c#
var list = Enumerable.Range(1,10000).ToList();
var hasElements = list.Count() > 0;
```

Anyメソッドを使う場合
```c#
var list = Enumerable.Range(1,10000).ToList();
var hasElements = list.Any();
```

Countメソッドを使った場合、すべての要素を数えるため、時間がかかる
Anyメソッドを使った場合、最初の要素を見つけた時点で処理を終了するため、早くなる

# 比較
以下記事で細かく書かれている
ベンチマークの結果としても、Anyメソッドの方がパフォーマンスが良い
https://dexall.co.jp/articles/?p=1527


# 結論
実際の現場では微々たる差異かもしれませんが、要素のあるなし判定をするときは、Countメソッドを使って要素有無を判定するより、Anyメソッドを使った方が効率的になる
コードを見ても、Anyの方が、直感的で分かりやすいため、要素数をカウントするのではなく、存在有無で判定していくと可読性も良くなる

(おまk)
.NETのバージョンよれば警告として出てきそう
https://learn.microsoft.com/ja-jp/dotnet/fundamentals/code-analysis/quality-rules/ca1827