OmniAICreator/Qiita-1.07M huggingface dataset:
ベルヌーイ試行と2項分布：成功確率のばらつきと中心極限定理の理解

## 概要
今回の記事では、ベルヌーイ試行、2項分布、中心極限定理について説明し、試行回数が増えると成功確率の分布がどのように正規分布に近づくかを実例とグラフで示します。

## セクション1: ベルヌーイ試行と2項分布の基本
ベルヌーイ試行とは、成功（1）または失敗（0）の二項結果を持つ試行です。例えば、コイン投げで表が出るか裏が出るかの試行がこれに該当します。

2項分布は、n回の独立したベルヌーイ試行の成功回数の分布を表します。具体的には、以下のような確率質量関数（PMF）を持ちます：

$$
P(X = k) = \binom{n}{k} p^k (1-p)^{n-k}
$$

ここで、
- $\( X \)$ は成功回数の確率変数
- $\( k \)$ は成功の具体的な回数
- $ \binom{n}{k} \$ は二項係数（n回中k回の成功の組み合わせ数）
- $\( p \)$ は各試行での成功確率
- $ (1-p) \$ は失敗確率

## セクション2: 中心極限定理
中心極限定理は、以下のように述べられる強力な数学の定理です：

> 「独立で同じ分布に従うランダム変数の和（または平均）は、その個々の変数の分布形状に関係なく、試行回数が増えるにつれて正規分布に近づく。」

この定理は、ベルヌーイ試行のような離散的な分布にも適用されます。

## セクション3: 2項分布の正規分布近似
ベルヌーイ試行は成功（1）か失敗（0）のいずれかの結果を持つ試行です。n回の独立したベルヌーイ試行の成功回数\( X \)は2項分布 \( \text{Binomial}(n, p) \) に従います。

中心極限定理により、試行回数nが十分に大きい場合、2項分布 $\( \text{Binomial}(n, p) \)$ は平均が$\( np \)$、分散が$\( np(1-p) \)$ の正規分布に近似できます。具体的には、次のように表現されます：

$$
X \sim \text{Binomial}(n, p) \approx \mathcal{N}(np, np(1-p))
$$

## セクション4: 試行回数と成功確率のばらつき
試行回数を増やすと以下のことが起こります：

1. **期待値に近づく**:
   - 成功回数の期待値は $\( np \)$ です。試行回数が増えると、実際の成功回数が期待値$ \( np \) $に近づく確率が高くなります。

2. **分散の減少**:
   - 2項分布の分散は $\( np(1-p) \) $です。試行回数が増えると、成功回数の分布が平均値 \$( np \)$ の周りで狭くなります（標準偏差が$ \( \sqrt{np(1-p)} \) $のため）。

## セクション5: 実例とグラフ
以下のコードは、PythonでPlotlyを使用して、試行回数が少ない場合と多い場合の2項分布をプロットし、それぞれ正規分布と比較する例です。

```python
import plotly.graph_objects as go
import numpy as np
from scipy.stats import binom, norm

# パラメータ
p = 0.5  # 成功確率
n_small = 5  # 小さい試行回数
n_large = 100  # 大きい試行回数

# 小さい試行回数の2項分布
x_small = np.arange(0, n_small + 1)
y_small = binom.pmf(x_small, n_small, p)

# 大きい試行回数の2項分布
x_large = np.arange(0, n_large + 1)
y_large = binom.pmf(x_large, n_large, p)

# 正規分布の近似
mu_large = n_large * p
sigma_large = np.sqrt(n_large * p * (1 - p))
x_norm_large = np.linspace(0, n_large, 1000)
y_norm_large = norm.pdf(x_norm_large, mu_large, sigma_large)

# プロット小さい試行回数
fig_small = go.Figure()
fig_small.add_trace(go.Bar(x=x_small, y=y_small, name=f'Binomial (n={n_small})'))

fig_small.update_layout(
    title='Binomial Distribution (n=5)',
    xaxis_title='Number of Successes',
    yaxis_title='Probability'
)

# プロット大きい試行回数
fig_large = go.Figure()
fig_large.add_trace(go.Bar(x=x_large, y=y_large, name=f'Binomial (n={n_large})', opacity=0.6))


fig_large.update_layout(
    title='Binomial Distribution (n=100)',
    xaxis_title='Number of Successes',
    yaxis_title='Probability',
    barmode='overlay'
)

fig_small.show()
fig_large.show()
```

### グラフについて
- **小さい試行回数（n=５）**:
  - 2項分布の棒グラフのみを表示。
  - 試行回数が少ないため、分布は非対称で正規分布にはならない。

- **大きい試行回数（n=100）**:
  - 2項分布の棒グラフと正規分布の線グラフを重ねて表示。
  - 試行回数が多くなると、2項分布が正規分布に近づく様子が視覚的に確認できる。

![スクリーンショット 2024-07-25 005139.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3364428/103cfcfe-feb2-9f72-c9f2-e6311553f85d.png)
![スクリーンショット 2024-07-25 005208.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3364428/240b775e-40cb-dfb0-6ea4-a1210f98e492.png)


## まとめ
試行回数を増やすことで成功回数のばらつきが減少し、予測しやすくなります。ベルヌーイ試行や2項分布の理解が深まると、さまざまな確率問題に応用できるでしょう。
AWSにおけるパブリックDNSの利用パターン

# はじめに
AWSにおけるパブリックDNSの利用パターンをいくつか解説をしていきたいと思います。

# パターン
①外部のDNSサーバでのドメイン管理、名前解決
外部のDNSサーバでドメインを管理し、そのDNSサーバにCNAMEレコードやAレコード等で、AWS上のリソースを登録するパターンです。既存ドメインが既に存在するパターンなどで利用することが多いでしょう。
②Route53でのドメイン管理、名前解決
Route53でドメインを購入するか、Route53をレジストラでDNS指定して、名前解決をRoute53で行うパターンです。
③外部のDNSサーバでのドメイン管理、サブドメインをRoute53に委任し、Route53での名前解決
外部のDNSサーバでドメインを管理していますが、サブドメインを払い出し、そのサブドメインの名前解決権限をRoute53に飲するパターンです。

# パターン１　外部のDNSサーバでのドメイン管理、名前解決
![スクリーンショット 2024-07-15 21.01.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584167/0026002e-8785-137f-81f0-8a29e5a3dd08.png)

このパターンでは、既存のDNSサーバやドメインが存在する場合、もしくはAWS外でドメインを管理したい場合に、外部のDNSサーバやサービスで名前解決を行います。この場合、当該ドメインを管理するDNSサーバにて、CNAMEレコードやAレコード等で、AWS側のリソースのFQDN、IPアドレスを指定します。
メリットとしてはドメイン管理を中央集権的に行っている組織での管理が容易になることが挙げられますが、デメリットとしては、Route53特有のレコードALIASレコードや、フェイルオーバールーティングの機能などが利用できないこと、AWS側のリソースと同一の環境で管理しないがための、登録にかかるリードタイム、ZoneApexに対してのCNAMEレコード登録不可等があげられます。

＃　パターン２ Route53でのドメイン管理、名前解決
![スクリーンショット 2024-07-15 21.01.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584167/e6389b29-0d7f-eda4-49bc-330ea921c612.png)

このパターンではAWS上で外部から購入したドメインやRoute53上で購入したドメインを管理し、Route53で名前解決を行う方式です。AWS上で完結するため、AWS特有の機能が利用できるメリットがあります。ALIASレコードによる、効率の良い名前解決や、フェイルオーバールーティングなどRoute53の便利な機能を利用することが可能です。

# パターン3 外部のDNSサーバでのドメイン管理、サブドメインをRoute53に委任し、Route53での名前解決
![スクリーンショット 2024-07-15 21.01.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584167/8c2a9fcf-7245-fcee-8551-918b6282a556.png)

ちょうど中間的なアプローチです。既存ドメインを管理するDNS上でサブドメインを払い出します。まず、Route53でサブドメインでパブリックホストゾーンを作成、当該パブリックホストゾーンのNSレコードを既存ドメインのDNSサーバでサブドメインのNSレコードとして登録することが可能です。権限を委任することで、Route53で名前解決が可能ですし、独自機能も利用できます。また、ゾーン自体がAWS側で管理となるため、レコードの追加変更が容易です。バックアップ・リストアなどでAWS上のFQDNが変わってしまった場合でも迅速に対応できるでしょう。

まとめ

|#  |方式  |メリット  |デメリット |
|---|---|---|---|
|1  | 外部のDNSサーバでのドメイン管理、名前解決|中央集権的な管理、既存ドメインへの影響なし|Route53の独自機能利用不可、ZoneApexに対するCNAMEレコード登録不可、運用時のリードタイム|
|2  |Route53でのドメイン管理、名前解決  |Route53独自の機能利用可、ZoneApexに対するALIASレコードの定義、運用時のリードタイム |中央集権的にドメインを管理している場合DNSが分散する|
|3|外部のDNSサーバでのドメイン管理、サブドメインをRoute53に委任し、Route53での名前解決|oute53独自の機能利用可、ZoneApexに対するALIASレコードの定義、運用時のリードタイム|ドメインが長くなったり、.が一つ増える、初期の既存ドメインとの調整コスト|

各方式をまとめてみました。個人的にはAWSのリソースはRoute53で管理することがおすすめです。
要件や運用方法などに合わせて最適な選択をしていきたいものですね。
【JavaSilver】配列

# 配列

* 配列は参照型				
* 配列はObjectクラスのサブクラス				
				
##### 配列型の初期化
```java:実装例
// ① 
int [] i = {10, 20, 30};
// ②
int [] i = {};
// ③
int [] i = new int[]{10, 20, 30};		
// ④ 
int i [] = new int[3];		
// ⑤　 
int array [];		
array = new int[]{};
// ⑥　 
int [] i = new int[3]{10, 20, 30}; // コンパイルエラー		
```
    
##### 二次元配列の初期化
```java:実装例
// ① 
int i[][] = new int[2][];		
i[0] = new int[2];
i[1] = new int[3];
// ② 
int[][] i = {{10, 20}, {30, 40}, {50, 60}};
```

* * *
```java:実装例
int [][] i = {{10, 20, 30}, {40, 50, 60}};			
System.out.println(i[0]); // 実行すると先頭配列のハッシュ値が出力
```

**・nullを代入できる**
```java:実装例		
String[] s = {null}; // Stirng型は参照型のため、nullも値として代入可
double[] s = {null}; // doubleも参照型	
double[] d = null;	
```

**・型変換**	
```java:実装例
A[] ary = new B[2];		
ary[0] = new A(); // B型の配列に、Aのオブジェクトを代入しているため	
ary[1] = new B();	
```

```:実行結果
実行時エラー
```

```java:実装例
A[] ary = new A[2];		
ary[0] = new A();		
ary[1] = new B(); // BクラスはAクラスのサブクラス
```

```:実行結果
実行成功
```				

```java:例題
class Item {			
    String name;		
    public Item (String name) {		
        this.name = name;	
    }		
}			
```
```java
public class Sample {			
    public static void main(String[] args) {		
        Item[] items = new Item[3];	
        item[1] = new Item["A"];	
        item[2] = new Item["B"];	
        for (Item item : items) {	
            System.out.print(item.name);
        }	
    }		
}
```
```:実行結果
NullPointerExceptionがスローされる
```

```java:例題
public class Sample {
    public static final int length = 3;
    public static void main(String[] args) {		
        int[] array = new int[length];	
        for (int i = 0; i < 3; i++) {	
            System.out.print(array[i]);
        }
        System.out.println();
        Integer[] array2 = new Integer[length];
        for (int i = 0; i < 3; i++) {	
            System.out.print(array2[i]);
        }
    }		
}
```
```:実行結果
000
nullnullnull
```

* 多次元配列を作成する場合は、すべて同じデータ型である必要がある。

```java:例題
public class Test {			
    public static void main(String[] args) {		
        Object[][] list = new Object[1][];	
        list[0] = new int[2]; // コンパイルエラー
        System.out.print(list[0][0]);	
        System.out.print(list[0][1]);	
    }		
}
```
```:実行結果
コンパイルエラー
```
透明物体への3D計測について調査中 その２: ASGrasp

### 想定する読者
- 透明物体の3D計測(DEPTHの補完処理)に関心のある人
- この例では、IntelのRealSense のようにRGB、left-IR, right-IR の出力が得られるセンサを前提としている。
    - StereoLabsのZED2iなどのセンサには適応できない手法になっている。


## [ASGrasp: Generalizable Transparent Object Reconstruction and 6-DoF Grasp Detection from RGB-D Active Stereo Camera](https://pku-epic.github.io/ASGrasp/)

>B. Experiment Setup
Hardware Setup. We use a 7-DoF Franka Panda arm
with its default two-finger gripper, on which we mount
an active stereo RGB-D camera, Intel Realsense D415.

RealSense のステレオのIR画像を用いている。

![](https://pku-epic.github.io/ASGrasp/images/Fig1.PNG)
Q: なぜ右側の画像の一群が、テーブルを白に固定してしまったのか？
![](https://pku-epic.github.io/ASGrasp/images/Framework.PNG)
このネットワークでは、RGBと、Left-IR, Right-IRとを入力画像にしている。
RealSenseと同じハードウェア構成を前提にするだろう。
そのため、StereoLabsのZED2iのように、left-RGB, right-RGB, depthの出力構成とは異なっている。

左側：Scene Reconstruction Module
右側: Grasp Detection Module (GSNet)
![](https://pku-epic.github.io/ASGrasp/images/depth_comparison.PNG)

https://arxiv.org/pdf/2405.05648

https://github.com/jun7-shi/ASGrasp

本論文では、透明物体や鏡面物体を把持する問題に取り組む。この問題は重要であるが、デプスカメラで正確な形状を復元できないため、ロボット工学の分野では未解決のままである。本論文では、RGB-Dアクティブステレオカメラを用いた6自由度把持検出ネットワークASGraspを提案する。ASGraspは、透過的な物体再構成を目的として、2層の学習ベースのステレオネットワークを利用し、乱雑な環境において、材料にとらわれない物体把持を可能にする。既存のRGB-Dベースの把持検出手法が、深度復元ネットワークや深度カメラによって生成された深度マップの品質に大きく依存しているのとは対照的に、我々のシステムは、透明オブジェクトの形状再構成のために生のIRおよびRGB画像を直接利用する能力によって差別化されている。我々は、GraspNet-1Billionをベースとした領域ランダム化により、広範な合成データセットを作成する。我々の実験により、ASGraspはシミュレーションと実世界の両方で、シームレスなシミュレーション-実世界転送により、一般化可能な透明物体把持の90%以上の成功率を達成できることが実証された。我々の手法は、SOTAネットワークを大幅に凌駕し、完全な可視点群入力によって設定された性能上限さえも凌駕する。   プロジェクトページ: https://pku-epic.github.io/ASGrasp

DeepL.com（無料版）で翻訳しました。


この研究では、透明オブジェクトの奥行き推定と把持検出を改善するために、市販製品（例えば、Intel R200やD400ファミリー）で一般的に見られるアクティブステレオカメラからの生のIR観測値を活用することを提案する。我々の洞察は、左右のIR観測値は、誤差の生じやすいステレオマッチングを経る前に、透明オブジェクトの奥行きのオリジナル情報を持ち、一方、RGB情報は余分な形状事前分布を提供することができるということである。そこで我々は、一般的なフロー推定ネットワークに基づいて、RGB画像と2つのIR画像の両方を入力とする、RGBを考慮した学習ベースのステレオマッチングネットワークを考案する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83761/aa99ffd9-e13f-f56a-b797-af0f26c0870b.png)
RGB 画像
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83761/952f8f60-ce48-0267-6a35-d3d10a6e1239.png)
left-IR 画像
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83761/64f38484-4a05-85d9-09f4-b9af89b8a93a.png)
right-IR 画像
出典　https://github.com/jun7-shi/ASGrasp/tree/main/test_data



#### 私見：
入力画像としてRight IR image, Left IR image, RGB imageを想定している時点で、RealSenseと類似の3Dカメラに対してしか使えないようだ。
そのため、RGBのステレオカメラでは、この手法は使えない。

## 不満
web ページにある動画例では、テーブルが白で色が均一な状況である。
このため、制御された環境での処理になっているんじゃないかと危惧する。
もっと、込み入った状況で、透明物体の背後の物体が写り込んでいるような状況での動作例を示してほしいところだ。

## SEE ALSO
[GSNet(GraspNet) 把持点抽出のためのライブラリ](https://qiita.com/nonbiri15/items/e5af265491779f119e43)
Hugging Faceモデルの量子化について深掘り

# Hugging Faceモデルの量子化について深掘り

## はじめに

最近、自然言語処理（NLP）の検証を行っている際にHugging Faceのモデルを選定する機会がありました。その際に、モデルの量子化（Quantization）の部分が理解できていなかったためいろいろと調べてみました。本記事では、Hugging Faceモデルにおける量子化の概念、実装方法、そして利点と課題について調査した内容をまとめました。

## 量子化とは

調べてみると、量子化（Quantization）の概念を理解することが重要だと感じました。この量子化というのは、モデルの重みや活性化関数の値を、より低精度のデータ型で表現する技術のようです。簡単に例えるなら、32ビット浮動小数点（float32）で表現されるこういった値を、8ビット整数（int8）などの低精度データ型に変換することを意味するようです。

### 量子化の主な目的

量子化を行う目的として、以下のようなものがあります。

1. モデルサイズの削減
2. 推論速度の向上
3. メモリ使用量の削減
4. エネルギー効率の改善

費用対効果もさることながら、量子化をちゃんとすることで用途にあった使い分けができそうですね。

## Hugging Faceにおける量子化

LLMのモデルを探す場合は、やっぱりHugging Faceとなりますが、Hugging Faceでは主に以下のような量子化手法が使用されているようです。

1. **8ビット量子化（INT8）**:
   - 最も一般的な量子化レベル
   - 元のモデルの精度に比較的近い性能を維持
   - ファイルサイズは32ビットモデルの約1/4に削減

2. **4ビット量子化（INT4）**:
   - より軽量な量子化レベル
   - ファイルサイズが大幅に削減されるが、精度も低下する可能性がある

3. **16ビット量子化（FP16）**:
   - 半精度浮動小数点を使用
   - 32ビットモデルに近い精度を維持しつつ、メモリ使用量を半減

4. **混合精度量子化**:
   - モデルの異なる部分に対して異なる精度を適用
   - 重要な層は高精度を維持し、その他の層は低精度化する

## 量子化の実装方法

量子化する際に、Hugging FaceではBitsandbytesライブラリと統合することにより、モデルの量子化が容易になっていようです。量子化を適用する基本的な手順はこんな感じです。

1. Bitsandbytesライブラリをインストール
2. モデルのロード時に量子化オプションを指定
3. 必要に応じて、キャリブレーションデータを用意
4. 量子化されたモデルを評価し、性能を確認

こちらは、Hugging Face公式ドキュメントに基づいた8ビット量子化の実装例です。

```python
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
import torch

model_id = "facebook/opt-350m"
quantization_config = BitsAndBytesConfig(
    load_in_8bit=True,
    llm_int8_threshold=6.0,
    llm_int8_has_fp16_weight=True,
)

tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(model_id, quantization_config=quantization_config)
```

## 量子化レベルの選択基準

量子化の実装方法まで見ていきましたが、量子化するためには用途にあった量子化レベルを選択する必要があります。量子化レベルを選択する際に検討する必要がある項目は下記の通りです。

1. **精度要件**：
   タスクに求められる精度レベルを明確にする。高精度が必要な場合は、FP16や8ビット量子化を選択する。

2. **計算資源の制約**：
   実行環境のメモリ容量や計算能力を評価する。リソースが限られている場合、4ビット量子化を検討する。

3. **レイテンシ要件**：
   リアルタイム性が求められる場合、より低い量子化レベルを選択して推論速度を向上させる。

4. **エネルギー効率**：
   バッテリー駆動デバイスなど、省電力が重要な場合は低い量子化レベルを選ぶ。

5. **モデルの特性**：
   モデルのアーキテクチャや規模によって、適切な量子化レベルが異なる場合がある。

6. **データの特性**：
   入力データの分布や特徴によって、量子化の影響が異なる場合がある。

7. **ハードウェアの互換性**：
   使用するハードウェアアクセラレータ（GPU、TPUなど）の量子化サポート状況を確認する。

## 量子化の利点と課題

量子化についていろいろとみてきましたが、最後に量子化する際の利点や課題をおさらいしてみましょう。

### 利点

1. **モデルサイズの削減**：
   量子化により、モデルのメモリフットプリントが大幅に削減される。これにより、リソースが制限された環境（エッジデバイスなど）での展開が容易になる。

2. **推論速度の向上**：
   低精度の演算は一般的に高速であるため、推論のレイテンシが減少する。

3. **エネルギー効率の改善**：
   量子化されたモデルは計算量が少なく、消費電力が低減される。

4. **エッジAIの実現**：
   量子化により、高性能なAIモデルをエッジデバイス上で直接実行することが可能になる。

### 課題

1. **精度の低下**：
   量子化レベルが低いほど、モデルの精度が低下するリスクがある。

2. **タスク依存性**：
   量子化の効果は、タスクやデータセットによって異なる場合がある。

3. **再学習の必要性**：
   場合によっては、量子化後のモデルを微調整（fine-tuning）する必要がある。

4. **ハードウェア互換性**：
   一部のハードウェアでは、特定の量子化レベルをサポートしていない場合がある。

## まとめ

Hugging Faceなどを含めてモデル選定時や利用する際は量子化とはなんぞや？というのを理解しておくことが重要でしょう。適切な量子化レベルを選択する際に気を付けることは、タスクの要件や利用可能なリソース、そして選定した量子化レベルで目標とするパフォーマンスが出せるかという点でしょう。8ビット、4ビット、16ビット量子化など様々な選択肢がある中で、それぞれの要件に応じて最適なものを選択することが大切だと感じました。

参考
https://huggingface.co/docs/optimum/concept_guides/quantization
【SOA】試験対策メモ その1

SOA取得のために勉強してます。

# RDSプロキシ
## 高速フェールオーバー機能
DBフェールオーバー後の接続先変更の処理が通常より早い。
普通はDNS変更を介すが、RDSプロキシからDBインスタンスに直接アクセスしてるから？

# S3
## アカウントレベルのパブリックアクセスブロック
S3のページから設定可能。ブロックパブリックアクセス設定（4つあるアレ）をアカウントレベルで設定できる。

https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/configuring-block-public-access-account.html

# ALB
## 静的IPについて
ALBのIPはいくつかのタイミングで変更される（ソース見つからなかった）。
そのため、ALBへのアクセスはDNS経由またはAレコードで行う必要がある。
静的IPを付与したい場合は、Global AcceleratorをALBの前に設定する方法がある。

# AWS IAM Identity Center
## 概要
AWSアカウントや他SaaS等のIDを一元管理できるサービス。
AWS Organizationsと統合可能。

# EFS
## 暗号化設定の有効化
ファイルシステム作成時のみ設定可能。
後から有効化する場合は、新しくファイルシステムを作成・暗号化し、元あったファイルを移動させる必要がある。

# EC2
## InsufficientInstanceCapacity
Insufficient：不十分
指定したインスタンスタイプがAWS側で用意できないエラー。
AZ、インスタンスタイプ単位で発生する。
AZを変える、インスタンスタイプを変更することで対処できる。

## リージョンを跨いだAMIの使用
AMIはリージョン固有のリソースのため、別リージョンで使用する場合はコピーが必要。

## 詳細モニタリング
いつでも設定可能。すべてのメトリクスが1分間隔で評価される。デフォは5分。

# Amazon Inspector
## 概要
EC2やlambda、ECRイメージなどをスキャンし、脆弱性などを検知するサービス。
アプリ特化な感じ。

# GuardDuty
## 概要
AWS アカウントとワークロードを継続監視するサービス。
アカウント全体のユーザーアクティビティを見てくれる感じ。

# EBS
## 汎用SSD(gp3)
最大16000IOPS
1GB~16TB

# Amazon CloudWatch
## メモリ使用率、ディスク使用率
基本モニタリングには入っていない。
EC2であればcloudwatchエージェントのインストールが必要

# lambda
## メモリ増強
できる

https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/configuration-memory.html

# Aurora
## バックトラック
インスタンスをある地点にデータ状態を戻す。

https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/AuroraMySQL.Managing.Backtrack.html

## ポイントインタイムリカバリ
ある地点のデータ状態を持つインスタンスを再作成（リストア）する。

https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/aurora-pitr.html

# CloudFormation
## cfn-signal
EC2などのリソースから、CloudFormationへシグナルを送信するスクリプト。
userdata内で実行することで、CloudFormationへリソース作成の完了を知らせることができる。
cfnのテンプレート内では、CreationPolicyブロックで受信するための設定を記載する。
yukicoder 解説集

# この記事について
yukicoderに書いた解説記事を、このサイトにすべてまとめる。そんな記事である。
解説ができ次第リンクを追加していく。
# 解説たち
[No.3 ビットすごろく](https://qiita.com/kazuppa/items/94b1b33cbaf85156f20b)
[No.4 重りと天秤](https://qiita.com/kazuppa/items/e948f21848d259dfaa86)
[No.5 数字のブロック](https://qiita.com/kazuppa/items/2a28a47f930098eed44a)
[No.7 プライムナンバーゲーム](https://qiita.com/kazuppa/items/c5226ed869c2a7108cce)
[No.8 N言っちゃダメゲーム](https://qiita.com/kazuppa/items/230f714019d63b389965)
[No.11 カードマッチ](https://qiita.com/kazuppa/items/ed38c91d8b6603df3193)
[No.16 累乗の加算](https://qiita.com/kazuppa/items/ffd21bc2395a6b517cb6)
[No.18 うーさー暗号](https://qiita.com/kazuppa/items/c084bc639d6d21b74068)
[No.21 平均の差](https://qiita.com/kazuppa/items/9065dc73e6c542ea5346)
[No.22 括弧の対応](https://qiita.com/kazuppa/items/c85a170a3d97b55af933)
[No.24 数当てゲーム](https://qiita.com/kazuppa/items/3cab71644166d7bae5e3)
[No.26 シャッフルゲーム](https://qiita.com/kazuppa/items/6d1cfc19a803732f767b)
[No.29 パワーアップ](https://qiita.com/kazuppa/items/bd758681eb510eb9052e)
[No.32 貯金箱の憂鬱](https://qiita.com/kazuppa/items/215abbfa4a5c4a866c67)
[No.35 タイパー高橋](https://qiita.com/kazuppa/items/ef5f1dfd7a75d3e37590)
[No.36 素数が嫌い！](https://qiita.com/kazuppa/items/5ac3e3851cb804fe102a)
[No.39 桁の数字を入れ替え](https://qiita.com/kazuppa/items/3b8921890d4f93223cd4)
[No.46 初めのN歩](https://qiita.com/kazuppa/items/191dbccb39cbba1a6b5d)
[No.47 ポケットを叩くとビスケットが２倍](https://qiita.com/kazuppa/items/eb706bed2eb27de7f0ae)
[No.48 ロボットの操縦](https://qiita.com/kazuppa/items/ab246c8ca6e54fc4a66d)
[No.51 やる気の問題](https://qiita.com/kazuppa/items/e7c00e8ad5beeadf907f)
[No.52 よくある文字列の問題](https://qiita.com/kazuppa/items/6373e39a81715b75368b)
[No.56 消費税](https://qiita.com/kazuppa/items/8a084392733b84011c6d)
[No.57 ミリオンダイス](https://qiita.com/kazuppa/items/4615af93957b1de86733)
[No.63 ポッキーゲーム](https://qiita.com/kazuppa/items/73e3aa6a758c879fc729)
[No.64 XORフィボナッチ数列](https://qiita.com/kazuppa/items/5cb0dd22bfc65f401e7d)
[No.65 回数の期待値の練習](https://qiita.com/kazuppa/items/b660d707cb74184193b3)
[No.69 文字を自由に並び替え](https://qiita.com/kazuppa/items/9bca395506728b24a663)
[No.70 睡眠の重要性！](https://qiita.com/kazuppa/items/b774be79aabae9ff393b)
[No.71 そろばん](https://qiita.com/kazuppa/items/4fcfd017cf6b8f51bb6f)
[No.79 過小評価ダメ・ゼッタイ](https://qiita.com/kazuppa/items/d9f36ada10aaa4dabd34)
[No.80 四角形を描こう](https://qiita.com/kazuppa/items/a6ec12c8ed9a9873e5fa)
[No.82 市松模様](https://qiita.com/kazuppa/items/8e041442bffd0c275026)
[No.83 最大マッチング](https://qiita.com/kazuppa/items/18b4cb795beeeade7763)
[No.2599 Summer Project](https://qiita.com/kazuppa/items/285a5bb97b763b55d43e)
[No.2607 Add One Digit](https://qiita.com/kazuppa/items/cbd347dcd1b5bd7086c6)
[No.2621 Fee Schedule](https://qiita.com/kazuppa/items/7edb1f191b0a16135f3e)
[No.2637 Factorize?](https://qiita.com/kazuppa/items/2885ad2ddcc9669e9fbb)
[No.2781 A%B問題](https://qiita.com/kazuppa/items/4792e701e7e120f9bfe7)
[No.2789 hako111223’s Master Thesis](https://qiita.com/kazuppa/items/c92cb60d084c9963eee7)
[No.2791 Beginner Contest](https://qiita.com/kazuppa/items/4a44170bb3f3bcfa4db9)
Unityで作るImmersive Audio環境

## ImmersiveAudioとは

Immersiveというのは、「没入感」という意味です。
つまり「イマーシブ オーディオ」とは「没入感の高いオーディオ」という意味になります。
一般的には、たくさんのスピーカーを配置したり、ヘッドフォンでの再生でも特殊な処理を行うことにより、360度、全方位から音が聞こえるコンテンツを「イマーシブ オーディオ」と呼んでいます。「立体音響」「3Dサラウンド」「Spacial Audio」など様々な呼び名がありますが、基本的に全て同義語と考えて間違いありません。

＞ https://biz.musicecosystems.jp/blog/what-is-immersive/



    using UnityEngine;
    
    [RequireComponent(typeof(AudioSource))]
    public class AudioDistanceControl : MonoBehaviour
    {
        public AudioSource audioSource;
        public Transform listenerTransform;
        public float maxDistance = 10f;
        public float minDistance = 1f;
        [Range(0f, 1f)] public float maxVolume = 1f;
    
        void Update()
        {
            float distance = Vector3.Distance(listenerTransform.position, transform.position);
    
            if (distance < minDistance)
            {
                audioSource.volume = maxVolume;
            }
            else
            {
                audioSource.volume = maxVolume - Mathf.Clamp01((distance - minDistance) / (maxDistance - minDistance)) * maxVolume;
            }
    
            if (!audioSource.isPlaying && audioSource.volume > 0)
            {
                audioSource.Play();
            }
        }
    
        // ギズモを使用して最小距離と最大距離をエディタに表示
        void OnDrawGizmos()
        {
            // 最小距離を示すギズモ（青色）
            Gizmos.color = Color.blue;
            Gizmos.DrawWireSphere(transform.position, minDistance);
    
            // 最大距離を示すギズモ（赤色）
            Gizmos.color = Color.red;
            Gizmos.DrawWireSphere(transform.position, maxDistance);
        }
    }
yukicoder No.46 初めのN歩　解説

[問題文](https://yukicoder.me/problems/no/46)
# 解説
まず、$BmodA=0$なら答えは$B/A$になる。
そうでないなら答えは$B/A+1$になる。
今回の場合だとbool型で$BmodA$がTrueになるか判定すればいい。
# C++での解答例
```C++
#include <bits/stdc++.h>
using namespace std;

int main(){
  int a,b;cin>>a>>b;
  cout<<b/a+(bool)(b%a)<<endl;
}
```
ESP32を使用した端末間通信

*esp32を使用する環境構築はできている前提として進めます。

# ESP32のmacアドレスの取得

端末間通信の前提として　送信側受信側それぞれのmacアドレスを確認しておきましょう。

以下コード
### 送信、受信側共通
```
#include <WiFi.h>
void setup() {
  Serial.begin(115200);
  while (!Serial) {
    ; // シリアルポートの準備ができるまで待機
  }
  // Wi-Fiを初期化
  WiFi.mode(WIFI_MODE_APSTA);  // STAとAPの両方のモードを有効にする
  WiFi.begin();
  delay(1000);  // 1秒待機
  // STAモードのMACアドレスを取得して表示
  Serial.println("ESP32 STA MAC Address: " + WiFi.macAddress());
  // APモードのMACアドレスを表示
  Serial.println("ESP32 AP MAC Address: " + WiFi.softAPmacAddress());
}
void loop() {
}
```
これによりSTA (ステーションモード)のmacアドレスとAP(アクセスポイントモード)のmacアドレスが取得できる。
セキュリティの観点から、このコードは毎回実行するのではなく、どこかにメモしておく事をお勧めする。


# 送受信のテスト
esp1とesp2を準備し、esp2にesp1から挨拶するコードを作成し、テストします。
*受信側のSTA macアドレスを16進数で入力する必要があります。(先ほど調べたmacアドレスを変換してください)

### 送信側
```
#include <esp_now.h>
#include <WiFi.h>
uint8_t broadcastAddress[] = {0x, 0x, 0x, 0x, 0x, 0x}; // 受信側のMACアドレスを入力
typedef struct struct_message {
    char msg[32];
} struct_message;
struct_message myData;
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
    Serial.print("\r\nLast Packet Send Status:\t");
    Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
}
void setup() {
    Serial.begin(115200);
    WiFi.mode(WIFI_STA);
    if (esp_now_init() != ESP_OK) {
        Serial.println("Error initializing ESP-NOW");
        return;
    }
    esp_now_register_send_cb(OnDataSent);
    esp_now_peer_info_t peerInfo;
    memcpy(peerInfo.peer_addr, broadcastAddress, 6);
    peerInfo.channel = 0;
    peerInfo.encrypt = false;

    if (esp_now_add_peer(&peerInfo) != ESP_OK) {
        Serial.println("Failed to add peer");
        return;
    }
    strcpy(myData.msg, "hello esp2 from hello esp1");
}
void loop() {
    esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
    if (result == ESP_OK) {
        Serial.println("Sent with success");
    } else {
        Serial.println("Error sending the data");
    }
    delay(2000); // 2秒ごとに送信
}


```

### 受信側
特に編集は必要なし。
```
#include <esp_now.h>
#include <WiFi.h>
typedef struct struct_message {
    char msg[32];
} struct_message;
struct_message myData;
// 新しいコールバック関数のシグネチャに対応
void OnDataRecv(const esp_now_recv_info *info, const uint8_t *incomingData, int len) {
    memcpy(&myData, incomingData, sizeof(myData));
    Serial.print("Bytes received: ");
    Serial.println(len);
    Serial.print("Message: ");
    Serial.println(myData.msg);
}
void setup() {
    Serial.begin(115200);

    WiFi.mode(WIFI_STA);
    if (esp_now_init() != ESP_OK) {
        Serial.println("Error initializing ESP-NOW");
        return;
    }
    esp_now_register_recv_cb(OnDataRecv);
}
void loop() {
    // メインループには何も書かなくても良い
}

```

シリアルモニタに 
```  Message: hello esp2 from hello esp1```
と表示されていれば成功
yukicoder No.39 桁の数字を入れ替え　解説

[問題文](https://yukicoder.me/problems/no/39)
# 解説
入れ替えといわれるとswapを思い出すだろう。
ただswapは整数型の桁には使えないので、文字列でできないか考える。
ここで、**答えとなる数字と元の数字の桁は変わらない**ということが言える。
つまり、辞書順比較による事故（10<100<11みたいな）が起こらない。
よって、事前にstring型としていい感じにswapをし、辞書順で遅かったらそれを答えの候補にするといいう感じでできる。
# C++での解答例
```C++
#include <bits/stdc++.h>
using namespace std;

int main(){
  string n;cin>>n;
  string ans=n;
  for(int i=0;i<n.size();i++)
    for(int j=i+1;j<n.size();j++){
      string t=n;
      swap(t[i],t[j]);
      ans=max(ans,t);
    }
  cout<<ans<<endl;
}
```
【C言語】本の整理 (paizaランク A 相当)をやってみた

**paiza×Qiitaコラボキャンペーン** ということで
[本の整理 (paizaランク A 相当](https://paiza.jp/works/mondai/real_event/book_sort)
をC言語でやってみました。

``` C
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    int i, j, min_idx, count = 0, nbook, *books;

    /* 入力データ取得 */
    fscanf(stdin, "%d", &nbook);
    books = calloc(nbook, sizeof(int));
    for (i = 0; i < nbook; i++){
        fscanf(stdin, "%d", &books[i]);
    }

    /* 問題文通りのアルゴリズム */
    for (i = 0; i < nbook; i++){
        for (j = i, min_idx = i; j < nbook; j++){
            if (books[j] < books[min_idx]){
                min_idx = j;
            }
        }
        /* i ≠ min_idxなら、i番目の本と min_idx番目の本を入れ替える。*/
        if (i != min_idx){
            int tmp = books[i];
            books[i] = books[min_idx];
            books[min_idx] = tmp;
            count++;
        }
    }
    printf("%d\n", count);
}
```

問題文通りにそのまま実装しています。
(x) x (y)のかけざんをかんがえて遊ぶ(プラマイ二乗法)(ベンチマークテスト)



x 過去ログを見てね!!

x SSD1306の画面のサイズが128ドットの64ドットなので127 x 127 で足ります。

目的
表引きプラスアルファーとハード乗算器を比べて遊ぶ

結果　あまり変わらず


●表引きプラスアルファー


![o_coq237.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/aa942e6c-515d-8e2c-351f-f028973f41f4.jpeg)



●ハード乗算器


![o_coq238.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/04a59e69-9ec6-b125-ccc5-9819baa612d3.jpeg)




プログラム


表引きプラスアルファー


```c++


//kakezan_soft_UNO_1

unsigned int ni_no_nijyou[] = {
0,1,4,9,16,25,36,49,
64,81,100,121,144,169,196,225,
256,289,324,361,400,441,484,529,
576,625,676,729,784,841,900,961,
1024,1089,1156,1225,1296,1369,1444,1521,
1600,1681,1764,1849,1936,2025,2116,2209,
2304,2401,2500,2601,2704,2809,2916,3025,
3136,3249,3364,3481,3600,3721,3844,3969,
4096,4225,4356,4489,4624,4761,4900,5041,
5184,5329,5476,5625,5776,5929,6084,6241,
6400,6561,6724,6889,7056,7225,7396,7569,
7744,7921,8100,8281,8464,8649,8836,9025,
9216,9409,9604,9801,10000,10201,10404,10609,
10816,11025,11236,11449,11664,11881,12100,12321,
12544,12769,12996,13225,13456,13689,13924,14161,
14400,14641,14884,15129,15376,15625,15876,16129,
16384,16641,16900,17161,17424,17689,17956,18225,
18496,18769,19044,19321,19600,19881,20164,20449,
20736,21025,21316,21609,21904,22201,22500,22801,
23104,23409,23716,24025,24336,24649,24964,25281,
25600,25921,26244,26569,26896,27225,27556,27889,
28224,28561,28900,29241,29584,29929,30276,30625,
30976,31329,31684,32041,32400,32761,33124,33489,
33856,34225,34596,34969,35344,35721,36100,36481,
36864,37249,37636,38025,38416,38809,39204,39601,
40000,40401,40804,41209,41616,42025,42436,42849,
43264,43681,44100,44521,44944,45369,45796,46225,
46656,47089,47524,47961,48400,48841,49284,49729,
50176,50625,51076,51529,51984,52441,52900,53361,
53824,54289,54756,55225,55696,56169,56644,57121,
57600,58081,58564,59049,59536,60025,60516,61009,
61504,62001,62500,63001,63504,64009,64516,65025,
65536
};


void setup() {
  //シリアルポートの初期化
  Serial.begin(9600);
  
  Serial.println();
  Serial.print("START");
  Serial.println();
}//setup

unsigned long time;

void loop() {

  char x, y;
  int z;
  int c = 0;

  Serial.print("TIME");

  time = millis();

  for (char ii = 127; ii != 0; ii--) {
    for (char jj = 127; jj != 0; jj--) {

      x = (char)random(128);
      y = (char)random(128);

      //z = x * y;

      z = (ni_no_nijyou[x+y] - ni_no_nijyou[abs(x-y)]) >> 2;

      if (z > 8192) {c++;}

    }//for jj
  }//for ii

  time = millis() - time;
  Serial.print((int)time);
  Serial.print("mS");
  Serial.print("  ");
  Serial.println(c);

}//loop



```
[date-fns] JST環境下で eachDayOfInterval に UTC時刻を突っ込んだ時の挙動が微妙な話

## 本資料における前提
システムのタイムゾーンはJSTとする。

## まずは問題のないケース
27日、28日、29日の連続した日付を生成したいとき、以下のようにJST時刻を使用しparseISOでDateオブジェクトを生成する。こうすることで、問題なく連続した日付を生成することができる。というか一般的にはこうすると思う。


```ts
import { eachDayOfInterval, parseISO } from "date-fns";

test("JSTを使った場合の eachDayOfInterval の挙動が意図通りか確認するテスト", () => {
  const start = parseISO("2024-07-27T00:00:00+09:00");
  const end = parseISO("2024-07-29T00:00:00+09:00");
  const dateList = eachDayOfInterval({ start, end });
  expect(dateList).toEqual([
    parseISO("2024-07-27T00:00:00.000+09:00"),
    parseISO("2024-07-28T00:00:00.000+09:00"),
    parseISO("2024-07-29T00:00:00.000+09:00"),
  ]);
});

```

## 問題となるようなケース
ところが、なんらかの事情によりJSTではなくUTC時刻によって生成されたDateオブジェクトをbeginとendに与えて、UTCのまま計算したいケースがあるかもしれない。UTCで渡してしまうと、以下のようにUTC時刻27日から返してほしくてもUTC26日から返してしまう。

```ts
test("UTCを使った場合の eachDayOfInterval の挙動が意図通りか確認するテスト", () => {
  const start = parseISO("2024-07-27T00:00:00Z");
  const end = parseISO("2024-07-29T00:00:00Z");
  const dateList = eachDayOfInterval({ start, end });
  expect(dateList).toEqual([
    parseISO("2024-07-27T00:00:00.000Z"), // actual: 2024-07-26T15:00:00.000Z
    parseISO("2024-07-28T00:00:00.000Z"), // actual: 2024-07-27T15:00:00.000Z
    parseISO("2024-07-29T00:00:00.000Z"), // actual: 2024-07-28T15:00:00.000Z
  ]);
});
```

「date-fnsはタイムゾーンが考慮されない」ということを考えれば当たり前では？と思える人はここで読むのをやめてもらっても構いません。[同様のissue](https://github.com/date-fns/date-fns/issues/2181)があることからも、この挙動に関して不思議に思うのは自分だけではないはず。

## 解決方法
いくつかあると思うが、最も理解しやすい方法は、UTC0時ではなく15時でDateオブジェクトを生成すれば良い。

```ts
test("UTC15時であれば eachDayOfInterval の挙動が意図通りか確認するテスト", () => {
  // utc date
  const start = parseISO("2024-07-27T15:00:00Z");
  const end = parseISO("2024-07-29T15:00:00Z");
  const dateList = eachDayOfInterval({ start, end });
  expect(dateList).toEqual([
    parseISO("2024-07-27T15:00:00.000Z"),
    parseISO("2024-07-28T15:00:00.000Z"),
    parseISO("2024-07-29T15:00:00.000Z"),
  ]);
});
```

## なぜこうなるのか

以下の処理が行われることにより、最初と最後の日付が1日ずれてしまい意図していない挙動になると推測する。

1. 開始時刻`utc1`がUTCで与えられることにより、JST`jst1`に変換する
2. 1日目の日付`d1`に`jst1`を当日00:00に巻き戻した結果を代入する
3. `d1`をUTC時刻`utc1'`に戻すと、UTCから見た場合に前日まで巻き戻りすぎてしまっている
4. 同様に終了時刻`utc2`についても`jst2`に変換する
5. 最終日の日付`dn`を計算するために`jst2`を当日00:00に巻き戻す
6. `dn`をUTC時刻`utc2`に戻した時もやっぱり前日まで戻りすぎてしまっている

先ほどのうまくいかない例で説明すると、

1. `utc1 = 7/27 00:00 (UTC)` なので、 `jst1 = 7/27 09:00 (JST)` に変換される
2. `jst1`を巻き戻すので `d1 = 7/27 00:00 (JST)`
3. `d1` を UTCに戻すと、 `utc1' = 7/26 15:00 (UTC)`であり、本当はUTCでも27日を期待しているのに、UTCだと7/26になってしまう
4. `utc2 = 7/29 00:00 (UTC)`なので、`jst2 = 7/29 09:00 (JST)` に変換される
5. `jst2`を巻き戻すので `dn = 7/29 00:00 (JST)`
6. `dn` を UTCに戻すと、 `utc2' = 7/28 15:00 (UTC)`であり、本当はUTCでも29日を期待しているのに、UTCだと7/28になってしまう


## 感想
時間情報がいらないケースって結構あると思うけど、どうしてDateとDateTimeをわけないのだろう。
成田悠輔の投稿に関するニュースから思うこと（小学生時代を懐かしむ状況を考える）

https://www.nikkansports.com/m/entertainment/news/202407270000390_m.html

いま振り返ると当時は環境が変わる度に新鮮な気持ちで全力で取り組んでいた。小学校、転校、中学校、高校、大学、就職、異動。
当時を懐かしみながら、いま漠然と同じ時間を過ごしているように感じつつも、現状の繰り返しを心地よく感じているのは、きっと新しい刺激が薄くなって脳が腐り始めているのかも。
何かしら環境を変えた方がいいのかもしれない。
ヌルポも怖くない、Javaでの比較について

## Javaで比較する術は？
業務で比較について勉強することがあったので、記事にまとめておくよ。
javaで比較するときによく使うものとして、
`equals()`、`==`、`Objects.equals`があるのでそれぞれ簡単に解説するよ。

### equalsメソッド(String.equals())
equalsメソッドは、Stringクラスの文字列を比較するときに利用されるものだよ。
ただし、nullと比較する場合にヌルポ（NullPointerException）が発生することもあるので、注意が必要だよ。基本的な使い方は以下の通り。
```java
str1.equals(str2);
```
具体的には、
```java
public class Main {
    public static void main(String[] args) {
        String str1 = "Qiita";
        String str2 = "Qiita";
        String str3 = "qiita";

        System.out.println(str1.equals(str2));
        System.out.println(str1.equals(str3));
    }
}
```
```
// 実行結果
true
false
```
ただし、nullとの比較の場合はこんな感じ。
```java
public class Main {
    public static void main(String[] args) {
        String str1 = "Qiita";
        String str2 = null;

        System.out.println(str1.equals(str2)); //false
        System.out.println(str2.equals(str1)); //ヌルポ発生
        System.out.println(str2.equals(str2)); //ヌルポ発生
    }
}
```
まとめると以下のようになるよ。
* `nullでない値.equals(nullでない値)`→比較可能
* `nullでない値.equals(null)`→false
* `null.equals(nullでない値)`→ヌルポ
* `null.equals(null)`→ヌルポ

### == 演算子
`==`は変数の値が等しいかを検証する演算子だよ。プリミティブ型は値が等しいか（同値性）を検証し、オブジェクト型では同じインスタンスであるか（同一性）を検証するよ。詳しくは書くとややこしくなるので、今回は簡単にだけ解説するよ。
まずはプリミティブ型の比較だよ。
```java
public class Main {
    public static void main(String[] args) {
        int num1 = 1;
        int num2 = 1;
        int num3 = 2;

        System.out.println(num1 == num2);
        System.out.println(num1 == num3);
    }
}
```
```java
// 実行結果
true
false
```
次にオブジェクト型の比較だよ。ここはコンスタントプールといったJavaの仕組み等が関係しているので、気になる方は調べてみてね。
```java
public class Main {
    public static void main(String[] args) {
        String str1 = "Qiita";
        String str2 = "Qiita";
        String str3 = new String("Qiita");

        System.out.println(str1 == str2);
        System.out.println(str1 == str3);
    }
}
```
```java
// 実行結果
true
false
```


### Objects.equals()メソッド
`Objects.equals()`は`String.equals()`とは使い方が違うよ。
`String.equals()`はヌルポが発生する可能性があるのに対して、`Objects.equals()`の場合はヌルポが発生しないよ。
```java
Objects.equals(str1, str2);
```

具体的な使い方はこんな感じ。

```java
import java.util.Objects;

public class Main {
    public static void main(String[] args) {
        String str1 = null;
        String str2 = "Qiita";
        String str3 = null;

        System.out.println(Objects.equals(str1, str2));
        System.out.println(Objects.equals(str1, str3));
    }
}
```

```java
// 実行結果
false
true
```

## まとめ
Javaで比較するには、`Objects.equals()`を使うとかなり便利。ただし、プリミティブ型の比較の場合は`==演算子`を用いた方が可読性や処理速度が上がるため使い分けが必要だよ。
LeetCode挑戦日記：Day41

# はじめに

最近、業務で実装する時間よりも資料作成やレビューをする時間が多くなってきました。
このままでは自身のコーディング能力が落ちそうで怖いので、LeetCodeを始めてみました。

自身の学習の記録 & LeetCodeに興味のある人が挑戦しやすいように、記事に残していきます。
このような競技プログラミングをした経験がないので、ひよってEasyからやっていきます...

# [Easy] 700. Search in a Binary Search Tree

二分探索木（BST）の`root`と整数`val`が与えられたとき、値が`val`と等しいノードを見つけ、そのノードを根とする部分木を返します。
もしそのようなノードが存在しない場合は`null`を返します。

## 素直に解いてみる

### 考え方

1. 全ノードを確認し、`val`と同じ値を持つノードを探す

### コーディング

```typescript
function searchBST(root: TreeNode | null, val: number): TreeNode | null {
    let node: TreeNode | null = null;
    const func = (root: TreeNode | null, val: number): void => {
        if (!root) { return; }
        if (root.val === val) {
            node = root;
        } else {
            func(root.left, val);
            func(root.right, val);
        }
    }
    func(root, val);

    return node;
};
```

### 結果

Runtime：66ms
Beats 85.12%

Memory：57.28MB
Beats 12.24%

## 二分探索木の制約を踏まえて検索する

### 考え方

二分探索木は、「`(左の子孫の値) <= (親の値) <= (右の子孫の値)`」の制約を持つ二分木

1. 各ノードの値に対して検索している値と比較し、子孫を選択してノードを検索する

### コーディング

```typescript
function searchBST(root: TreeNode | null, val: number): TreeNode | null {
    let node: TreeNode | null = root;

    while (node !== null) {
        if (node.val === val) { break; }

        if (node.val < val) {
            node = node.right;
        } else {
            node = node.left;
        }
    }

    return node;
};
```

### 結果

Runtime：60ms
Beats 96.23%

Memory：57.03MB
Beats 31.26%
The "SendWspARG" element in your flow has validation errors

+ [element in your flow has validation error](https://qiita.com/Keiji_otsubo/items/cef86af6c6c0f946af07)

-----------------------

+ [The element in your flow has validation errors - Error in Record-Triggered Flow](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007eqK0s)

:::note alert
The "SendWspARG" element in your flow has validation errors
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/b1258f53-8178-cfb1-fa5a-cb7d017e293a.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/6fe3fa39-d267-0d79-bd4c-6a35d1b1ac9a.png)
やったことがないタスクが怖い人へ。これを使えば楽勝です。


システムエンジニアをやっていく中で「細分化」するスキルがとても重要だと感じたため、ここらで一度整理しておこうと思います。

システムエンジニアになったはいいものの、抽象度の高いタスクを任されると困ったりする人の助けになればなと思います！

# 細分化とは

「細分化」するスキルとは、大規模で複雑なタスクや問題を小さく分割し、それぞれを管理しやすくする能力のことです。

具体的に何をやればいいかまで指定されているタスクはできるけど、「デザインも仕様も決まってないけどこんなもの実装して！」のような抽象度が高いタスクに苦戦してしまうという場合、抽象度の高いものを自分がこなすことができる粒度まで細分化してしまえばいいのです。

巨大な食べ物はロマンがありますが、そのままだと美味しくいただくことは難しいです。食べやすくなるように切り分けましょう。

今回は

- 実装したことがない機能の追加
- 工数の見積もり

例に細分化の力を見ていきましょう。

# 新しい機能を追加してくれ！

あなたは「Eコマースサイトにショッピングカート機能を追加してくれ！」と頼まれました。

（カート機能がないのにEコマースとしてリリースしてたの・・・？）という疑問は置いておいて、あなたはこの機能を実装しなければなりません。

慣れ親しんだ機能ではあるので成果物はなんとなくイメージがつきますが、どうやって開発すればいいのかわかりません。

細分化の力を使って、ショッピングカート機能を実装しましょう！

### 1. 全体の機能を把握する

「ショッピングカート機能」はさまざまな機能の集合体です。具体的にどのようなことができればいいのかを把握、細分化しましょう。

- 商品をカートに追加
- カート内の商品数量を更新
- 商品をカートから削除
- カートの内容を表示
- 合計金額を計算
- カートデータをサーバーに保存

### 2. タスクに分解する

先ほど細分化した機能について、より細かく細分化していきます。この段階で、どのような実装をすればいいのかイメージがつくレベルまで細かくしちゃいましょう！

- タスク1: 商品をカートに追加
    - 「カートに追加」ボタンを追加
    - ボタンがクリックされたときに商品をカートに追加
- タスク2: 商品数量を更新
    - 数量変更UIを追加
    - 数量変更時にカートを更新
- タスク3: 商品をカートから削除
    - 「削除」ボタンを追加
    - ボタンがクリックされたときに商品を削除
- タスク4: カートの内容を表示
    - カート内容表示UIを作成
    - カートデータを取得して表示
- タスク5: 合計金額を計算
    - 合計金額計算ロジックを実装
    - 合計金額を表示
- タスク6: カートデータをサーバーに保存
    - APIエンドポイントを作成
    - カートデータを送信

### 3. 順番にタスクを実装する

あとはタスク１から順番に（依存関係がある場合はそれを考慮しながら）実装していけばOKです！

# 「いつまでにできる？」に回答する

ある日、上司から新しいWebアプリケーションの開発を任されましたが、どれくらい時間がかかるか予測がつきません。この状況で、上司から「いつまでにできそうか知りたい」と言われた場合、物事を細分化するスキルを使って回答しましょう！

### 1. 全体の把握

まず、Webアプリケーション開発の全体像を理解し、各フェーズに分けます。

- 要件定義
- 設計
- 実装
- テスト
- デプロイメント

### 2. 各フェーズの細分化

各フェーズをさらに細かいタスクに分割します。

- **要件定義**:
    - クライアントとの打ち合わせ（4時間）
    - 要件文書の作成（8時間）
    - 要件確認ミーティング（2時間）
- **設計**:
    - システムアーキテクチャの設計（16時間）
    - データベース設計（8時間）
    - UI/UXデザイン（12時間）
- **実装**:
    - フロントエンド開発（40時間）
        - ホームページ（10時間）
        - ダッシュボード（15時間）
        - ユーザー管理機能（15時間）
    - バックエンド開発（40時間）
        - API開発（20時間）
        - 認証システム（10時間）
        - データベース接続（10時間）
- **テスト**:
    - 単体テスト（16時間）
    - 統合テスト（16時間）
    - ユーザーテスト（8時間）
- **デプロイメント**:
    - デプロイメント環境の設定（8時間）
    - アプリケーションのデプロイ（4時間）
    - モニタリング設定（4時間）

### 3. 各タスクの見積もり

上記の各タスクに対して、所要時間を見積もります（カッコ内に見積もり時間を記載）。

### 4. 合計時間の計算

各タスクの時間を合計して、全体の時間を算出します。

- 要件定義: 4 + 8 + 2 = 14時間
- 設計: 16 + 8 + 12 = 36時間
- 実装: 40 + 40 = 80時間
- テスト: 16 + 16 + 8 = 40時間
- デプロイメント: 8 + 4 + 4 = 16時間

合計時間は14 + 36 + 80 + 40 + 16 = 186時間だとわかります！

ここまで厳密に時間を計算しなくても「要件定義には10時間くらいかかりそうで、設計には30時間くらい欲しいな・・・」程度でも、全く細分化していない状態よりは精度が高い予測になります。

# 最後に

細分化の力を使って大きな問題を解決可能な大きさまで分けることができました。どうしたらいいのかわからない問題に直面した時は、ぜひ細分化を試してみてください！

細分化の例は生成系AIに作成してもらいました。「現在私は〜という問題に直面しています。問題解決までの手順を細かく区切って提案してください」と投げればそれなりの精度のものが返ってくるかもしれません。便利な世の中になりましたね。
NeoVimのオレオレ環境を作ってみた

# 概要
久しぶりにNeoVimでコーディング作業がしたい！と思い1からneovimのプラグインを選定し、セットアップしたのでついでにGitHubに公開してみんなに共有しよう！と、この記事を書いています。
# 目次
- [NeoVimとは](https://qiita.com/hihimamu/items/4d8632c036c98862e41c#neovim%E3%81%A8%E3%81%AF)
- [現在のセットアップ](https://qiita.com/hihimamu/items/4d8632c036c98862e41c#%E7%8F%BE%E5%9C%A8%E3%81%AE%E3%82%BB%E3%83%83%E3%83%88%E3%82%A2%E3%83%83%E3%83%97)
- [導入方法](https://qiita.com/hihimamu/items/4d8632c036c98862e41c#%E5%B0%8E%E5%85%A5%E6%96%B9%E6%B3%95)
- [最後に](https://qiita.com/hihimamu/items/4d8632c036c98862e41c#%E5%B0%8E%E5%85%A5%E6%96%B9%E6%B3%95)
# NeoVimとは
**NeoVim**とは古くからある**Vim**というエディタをよりモダンに拡張性や使いやすさのために刷新したVimの派生テキストエディタ
Vimと比べて以下のような相違点がある

- よりデベロッパフレンドリーな**API**や各種機能
- **Luaランタイム**を備えているため、Lua言語による設定の記述が可能
- **Tree-sitter(パーサー)** による強力な構文解析機能
  - より正確なsyntax highlight等
- 組み込み**LSP(Language Server Protocol)** クライアント
# 現在のセットアップ
現在の私のNeoVimはこんな感じ
![neovim.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3661758/c206b86a-a9ee-4581-1511-c22b90d0b045.png)
**fzf**やシンタックスハイライト、ファイラーやタブラインにバッファライン装飾のプラグイン、**Toggle Term**等が導入されている
操作向上系プラグインにはVScodeライクにスコープを開閉できるプラグイン等もある
# 導入方法
詳しくは私のリポジトリ[hihimamu.nvim](https://github.com/hihimamuLab/hihimamu.nvim)の[Required](https://github.com/hihimamuLab/hihimamu.nvim#required)、[Install](https://github.com/hihimamuLab/hihimamu.nvim#install)を見ること
# 最後に
今回私がセットアップしたNeoVimで多くの方のNeoVimライフが充実することを心より願います。
また、私のNeoVimを彩ってくれた[Plugins](https://github.com/hihimamuLab/hihimamu.nvim?tab=readme-ov-file#plugins)の皆様、ありがとうございました！
新規作成画面に入力項目が何もない


+ [Page layout for new record is completely blank](https://trailhead.salesforce.com//trailblazer-community/feed/0D54S00000A97NUSAZ)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/52b5de40-95ff-6464-b4eb-bf69fffb285a.png)

:::note
 UPDATE: I had two dynamic forms on my Lightning Page with similar fields, and a visibility filter based on one of those Fields. I moved overlapping fields to a generic section and was able to create the record from the New button.

 更新: Lightning ページに同様の項目を含む 2 つの動的フォームと、それらの項目の 1 つに基づく表示フィルターがありました。重複するフィールドを汎用セクションに移動し、[新規] ボタンからレコードを作成できるようになりました。
:::

+ [While creating an new Opportunity and Contact Role, I am unbale to crate or enter the details?](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007eqPOj)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/6c5a786d-7713-bbb7-a9a8-a9a655eb2250.png)


# こっちは編集画面

+ ["Edit" and "Clone" Buttons not working on opportunity (certain record type)](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54V00007JAN1fSAH)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/a7cee8b3-0f91-e440-1e87-9be4246838d5.png)


# no display contact Layout

+ [no display contact Layout](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007QbfBE)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/9f973796-bfa3-b660-5f8f-c763e889d99f.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/b0323582-9543-d17d-4380-9f155bc7fe73.png)


:::note
Could you check following things:

Field level security of Contact Object
Do you have proper permission sets?
Check Profile -> Object Level Settings -> Make sure fields you need to use have Read & Write access.
If above things do not help to find the issue, clear your cache and try again
:::

# Experience Cloud サイト

+ [【未解決】Experience Cloud サイトで、カスタム オブジェクトの関連リストにある標準の「新規」ボタンをクリックする (別のカスタム オブジェクトを作成する) と、ほぼ空白のページが表示されるという問題が発生しています](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX000000o7CJ)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/a5d26d6f-1272-f768-1602-48a94dce5c10.png)
PowerShell　 HtmlAgilityPack ライブラリ

[注記]本記事はChatGptの回答備忘録として記載しております。

PowerShell では、XPath を使用して HTML ドキュメント内の特定の要素を検索し、その InnerText を取得することができます。ここでは HtmlAgilityPack ライブラリを使用して、XPath に基づいて HTML を解析できます。

まず、HtmlAgilityPack をインストールする必要があります。以下の手順でインストールできます。

PowerShell で以下のコマンドを実行して HtmlAgilityPack をインストールします。
```
Install-Package HtmlAgilityPack
```
次に、以下のスクリプトを使用して、XPath を用いて HTML 要素を検索し、その InnerText を取得します。

```
# HtmlAgilityPackライブラリをインポート
Add-Type -Path ".\lib\HtmlAgilityPack.dll"

# HTMLファイルのパスを指定
$htmlFilePath = ".\MailContent~.html"

# HTMLファイルを読み込む
$htmlContent = Get-Content -Path $htmlFilePath -Raw

# HtmlDocumentオブジェクトを作成し、HTMLコンテンツをロード
$htmlDoc = New-Object HtmlAgilityPack.HtmlDocument
$htmlDoc.LoadHtml($htmlContent)

# XPathを使用して特定の要素を検索 (例: //div)
$nodes = $htmlDoc.DocumentNode.SelectNodes("//tr")

# 各ノードのInnerTextを取得して表示
foreach ($node in $nodes) {
    Write-Output $node.InnerText
}


```
このスクリプトのポイントは以下の通りです。

HtmlAgilityPack ライブラリをインポートします。
ローカルの HTML ファイルを読み込み、その内容を HtmlDocument オブジェクトにロードします。
XPath を使用して特定の要素を検索します（例：//div はすべての div 要素を検索します）。
各要素の InnerText を取得して表示します。
XPath クエリを変更することで、他の要素や属性に基づいた検索が可能です。例えば、特定のクラスを持つ div 要素を検索する場合は、以下のように XPath クエリを変更します。

```
# クラスが特定の値を持つdiv要素を検索
$nodes = $htmlDoc.DocumentNode.SelectNodes("//div[@class='specific-class']")
これにより、class 属性が specific-class であるすべての div 要素を検索し、その InnerText を取得できます。
```
iperf2のほうがいいかも(better than iperf3)?

# iperf2とipetf3
iperf2とiperf3とは互換性がない。違いを調べると、下記サイトが見つかる。
1. [Iperf 2 & Iperf 3 Comparison Table](https://iperf2.sourceforge.io/IperfCompare.html)
1. [iperf2 vs iperf3: What’s the difference?](https://www.questioncomputer.com/iperf2-vs-iperf3-whats-the-difference/)
1. [iperf2 / iperf3](https://fasterdata.es.net/performance-testing/network-troubleshooting-tools/iperf/)
1. [Change between iPerf 2.0, iPerf 3.0 and iPerf 3.1](https://iperf.fr/iperf-doc.php#3change)

最初のサイトの記載にあるように、iperf2ではサポートしているが、iperf3では未サポートの項目も多い。

ここでは小生の視点でコメント。

## iperf3のUDPモードにはTCP通信もある
Firewall設定配下で実行したときに、あらためて気がついたこと。Wiresharkデータは下記となる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/fd8036f0-0992-0d0a-46ae-1ace9f736ef6.png)
このTCPストリームは次のようなもの。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/ae54e05e-bf1d-4180-ea27-4457a3af295c.png)
Server側での測定結果をClient側に返すため、TCPを用いているようだ。これはこれで理解できるが、Firewall設定で、TCPポートを追加する必要がある。（場合によっては好ましくない。）

iperf2のUDPモードでは、UDPのみ使われる。
![UDPonly.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/c8cd150f-2339-72a3-31d7-7a905835a520.png)

## iperf2では、CSVで結果を得られる
'-y C'オプションにより、CSVで結果を得られる。
```
20240715183444,192.168.10.102,49833,192.168.10.202,5001,1,0.0-1.0,132096,1056768,1.877,0,258,0.000,0
20240715183445,192.168.10.102,49833,192.168.10.202,5001,1,1.0-2.0,131072,1048576,1.246,0,256,0.000,0
20240715183446,192.168.10.102,49833,192.168.10.202,5001,1,2.0-3.0,131072,1048576,2.375,0,256,0.000,0
20240715183447,192.168.10.102,49833,192.168.10.202,5001,1,3.0-4.0,130560,1044480,2.021,0,255,0.000,0
.....
```
iperf3では、JSONのみ対応し、CSV対応なし（iperf2ではJSON対応なし）。エクセルなどのアプリケーションへのインポートにはCSVのほうが、まだまだ便利と思われる（何らかの方法で変換すればいいだけかもしれないが）。

## iperf2では、Windows Powershellのteeコマンドが正しく機能する（iperf3では不十分）
iperf3では、リアルタイムに結果が表示されない（終了後に表示かつファイルへ格納）。どこかで調べたことがあるが、Linuxの新しいバージョンでは機能するが、Windowsの最新バージョンではNGらしい（サイト情報失念）。下記は、実行中のiperf3サーバーの様子。
![tee_does_not_work.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/87d3aef5-379b-f75d-6eae-f732b60c7eb4.png)
iperf2では、teeが正しく動作し、リアルタイムに結果が表示されるとともに、ファイルにも結果が格納される。下記は実行中の様子。
![tee_works.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/f719eb9e-776e-54be-acd7-0142a91e92d5.png)

EOF
robloxでassistant その145

# 概要
robloxでassistantやってみた。
練習問題、やってみた。

# 練習問題
plugninで、ReadMeを生成せよ。

# サンプルコード

```


local PluginBar = plugin:CreateToolbar("creator1")
local Button1 = PluginBar:CreateButton("creator", "Create new script", "rbxassetid://4458901886", "readme")

Button1.Click:Connect(function()
	if game:FindFirstChild("ReadMe") then
		game.ReadMe:Destroy();
	end
	local helloScript = Instance.new("Script", game)
	helloScript.Name = "ReadMe"
	helloScript.Source = [[
このpluginの目的は

]]
	print("ok")
end)


```

以上。
robloxでassistant その144

# 概要
robloxでassistantやってみた。
table使ってみた。

# サンプルコード

```

local stack = {}

table.insert(stack, 4)
table.insert(stack, 3)
table.insert(stack, 2)
table.insert(stack, 1)

for i in stack do
	print(stack[i])
end

print(table.remove(stack))

for i in stack do
	print(stack[i])
end

table.sort(stack)

for i in stack do
	print(stack[i])
end

print(table.find(stack, 4))


local n1, n2, n3 = table.unpack(stack)
print(n1)
print(n2)
print(n3)

local t = table.pack({10, 11, 12})
for i, v in stack do
	print(i .. " : " .. v)
end


```

# 実行結果

```
  09:57:04.561  4  -  クライアント - LocalScript:11
  09:57:04.561  3  -  クライアント - LocalScript:11
  09:57:04.562  2  -  クライアント - LocalScript:11
  09:57:04.562  1  -  クライアント - LocalScript:11
  09:57:04.562  1  -  クライアント - LocalScript:14
  09:57:04.562  4  -  クライアント - LocalScript:17
  09:57:04.563  3  -  クライアント - LocalScript:17
  09:57:04.563  2  -  クライアント - LocalScript:17
  09:57:04.563  2  -  クライアント - LocalScript:23
  09:57:04.563  3  -  クライアント - LocalScript:23
  09:57:04.564  4  -  クライアント - LocalScript:23
  09:57:04.564  3  -  クライアント - LocalScript:26
  09:57:04.564  2  -  クライアント - LocalScript:30
  09:57:04.564  3  -  クライアント - LocalScript:31
  09:57:04.564  4  -  クライアント - LocalScript:32
  09:57:04.565  1 : 2  -  クライアント - LocalScript:36
  09:57:04.565  2 : 3  -  クライアント - LocalScript:36
  09:57:04.565  3 : 4  -  クライアント - LocalScript:36
  
```

以上。