OmniAICreator/Qiita-1.07M huggingface dataset:
git diff をgithubみたいに見やすくしたい人へ　(左右画面分割diff , 差分ハイライト

こんな感じにおしゃれに。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/279062/d8d07b70-d609-b33a-77ea-8309672d77ab.png)

https://github.com/dandavison/delta
これ使う。

インストールはこちらのリンクから
https://dandavison.github.io/delta/installation.html


インストールが終わったら、 ```~/.gitconfig``` に設定を入れる。


自分の設定は

```~/.gitconfig
# github.com/dandavison/delta
[core]
    pager = delta

[delta]
    side-by-side = true
    features = unobtrusive-line-numbers decorations
    whitespace-error-style = 22 reverse

[delta "unobtrusive-line-numbers"]
    line-numbers = true
    line-numbers-left-format = "{nm:>4}┊"
    line-numbers-right-format = "{np:>4}│"
    line-numbers-left-style = blue
    line-numbers-right-style = blue

[delta "decorations"]
    commit-decoration-style =  box ul
    file-style = bold yellow ul
    file-decoration-style = none
    hunk-header-decoration-style = cyan box ul
```


好きなようにカスタマイズしてみてください。
UnityのRayFireの簡単な使い方

# 初めにUnity fo RayFireとは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711067/92478e75-db82-5fbe-ac7c-2db12d248264.png)

LayFireのオブジェクトへの射撃、 破壊、粉砕、崩壊、破砕、爆破、破裂、起爆、爆発などの効果をUnityで使えるようにしたAssetです。

## Unity fo RayFire購入

まずはAssetを買いましょう

https://assetstore.unity.com/packages/tools/game-toolkits/rayfire-for-unity-148690

assetstoreで購入をしたらプロジェクトにインポートしましょう
## Unity fo RayFire使い方
### オブジェクトが落ちたら壊れる
初めに適当にオブジェクトを置いてそのオブジェクトを破壊してみましょう

1.   まず初めに壊したいオブジェクトと床を設置しましょう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711067/8f27a5d6-7820-5a76-1660-7dc738f64686.png)
今回の場合は床はpanelにして壊したいオブジェクトをcubeにします

2. 壊したいオブジェクトにRayfireShatterを付ける
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711067/735c7be5-f233-96fe-72d9-e699f10efb5a.png)

3. 値をセットする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711067/1c0ebfdb-2acc-e72a-3b06-06e9c12c9f95.png)

|    |  主に使うもの  |
| ---- | ---- |
| Type | 破片の壊れ方 |
|Amount | オブジェクトの壊れた時の破片の数

とりあえず今回は初期設定でやってみましょう

4. 設定が終わったらオブジェクトを分解する
　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711067/21d1ec12-35f1-a523-6840-769253bfd3ed.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711067/4b98ae33-eb7b-ec36-dcc8-fcabd8144765.png)
**この時に分解されてないオブジェクトはsetactiveをfalseにしておきましょう**
5. 生成されたオブジェクトにRayfire Rigidを付ける
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711067/0122948d-6ad3-957c-6d20-048b16dd3094.png)

6. Rayfire Rigidの値を設定する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711067/7f05d309-60a1-2d2a-834f-25777c6c140b.png)

7. 確認する
![ezgif.com-gif-maker.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711067/defb8993-bc3e-62a3-5964-d0b4107ee394.gif)
このように壊れれば**成功**です

### オブジェクトがぶつかったら壊れる
**前の工程の1~5までは全く同じなので省略します**
1. RayfireRigidの値を設定する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711067/a0dd6acb-3461-38ab-285c-59341cb5669f.png)

2. 新しいオブジェクトを作りRayfireRigidの値を設定する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711067/329a6132-4a82-e383-4844-f5ed7943b9ad.png)

3. 確認してみる
![ezgif.com-gif-maker (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711067/762a51e0-b41c-60b1-e06f-45d99237c865.gif)
このように動けば完成です

### オブジェクトを爆発する
前の工程の1まで同じ工程なので省略します
1. 新しくオブジェクトりRayFire Bombを付ける
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711067/92b84d68-c406-9719-a280-0831f14e3452.png)

2. RayFire Bombの値の設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711067/cfe1b779-ec7c-55b3-c8f0-5a6d21f75c20.png)
設定が終わったらこのオブジェクトを破壊したいオブジェクトの座標に合わせてください

3. 確認
![ezgif.com-gif-maker (2).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711067/ed30a929-82fc-ba63-d0f9-bf1e8d25b9c5.gif)
このようにオブジェクトが破壊されたら成功です

# 応用
RayFireを使った応用は別の記事にございますので良ければ見て下さい

https://qiita.com/bakusoumaru/items/0be065ca0a3e5a543c9b
[EC2]自動起動・停止のスケジュール設定

開発環境で構築中のEC2インスタンスを使う時間帯だけ起動・停止させて料金おさえたろ、というときに。

https://it-study.info/eventbridge-ec2-start-stop/

の記事がわかりやすくまとまっていて、2022/06/25時点でもほぼこの記事の通りにいけた。
ほぼ、というのは「8行目を修正します。」となっていたところが、実際に操作したときには、
デフォルトで"Service": "events.amazonaws.com"になっていたので対応する必要なかった、というくらい。
2分で分かるSRE障害対応

# SRE障害対応

* 主に赤箇所の障害対応関連の記事になります。
![SRE - 06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/892a1fd0-9bce-62ad-d454-cf796a2c81b8.png)

* 開発部門と運用部門で目的や価値観が異なります。
![SRE - 07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/05a9d186-c3a2-0bfb-6bd7-4eb0f31cd61a.png)

* SLO、エラーバジェットという指標を両方のチームで共有します。
![SRE - 09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/0b606051-914c-5fed-643e-70859681c1f0.png)

* エラーバジェットに余裕があるないときは既存運用に集中します。
![SRE - 10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/5f2c9744-f203-3957-a385-e91a0a8534d5.png)


* SLOを守るためにモニタリングが必要です。障害発生時は下図の対応が行われます。
![SRE - 11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/1a1721b1-4eba-eb21-6e31-40e2488f9845.png)

* ヒートマップのようにSLOの達成率を可視化します。
![SRE - 13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/56e8a581-3966-36e1-1ee4-8a0d5a36b8e9.png)

* アラートは通知するか監視ツールのダッシュボードで確認します。
![SRE - 14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/7f4fa3f6-6de9-b41f-bf83-585fcfb05a0d.png)

* アラートを3種類に分類してページのみを通知します。
![SRE - 15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/fbe0ecd4-d692-390a-19ba-633e813b0bdf.png)

* 手順や体制を明確に定義して訓練をするのが重要です。
![SRE - 16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/3b58ab09-07ed-b60e-bfb4-fc6f07cb0f33.png)

* 障害の障害の振り返り、根本原因、対策計画、教訓をまとめて次に活かします。
![SRE - 17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/3cfe092f-c10d-db0f-1e51-f3bea74c8731.png)

* 人を責めないという組織文化が重要です。
![SRE - 18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/616ef52b-f887-a82e-efcf-2e8f5aa6d357.png)
Eloquentを使ってデータを全て取得したいんですけどっ！？？

# イントロ

今回はLaravelのEloquentを使って、そのテーブルの全てのデータを取得する方法を紹介するZE☆

以下の2つの使い方を紹介するよ！

- `get`メソッド
- `all`メソッド

# `get`メソッドで全てのデータを取得する

全てのデータを取得したいときは、モデルのあとに`get`メソッドを繋げる。

書き方は以下。

```PHP
$全部のデータ = モデル::get();
```

こうやって書くとそのモデルのデータを全部取得(=get)できる。

`get`メソッドを使った様々な例を見てみよう。

```PHP
/**
 * usersテーブルから全てのデータを取得する方法
 */
use App\Models\User; // 使いたいモデルを読み込む
$all_users = User::get(); // get()で全てのユーザーを取得できる

/**
 * postsテーブルから全てのデータを取得する方法
 */
use App\Models\Post; // 使いたいモデルを読み込む
$all_posts = Post::get(); // get()で全ての投稿を取得できる
```

# `all`メソッドでも全部を取得できる

今`get`メソッドを使うと、そのモデルのデータ全てを取得できると説明したが、同様の機能を`all`メソッドでも実現することができる。

```PHP
/**
 * booksテーブルから全てのデータを取得する方法
 */
use App\Models\Book;
$books = Book::all(); // all()でも取得できる

/**
 * authorsテーブルから全てのデータを取得する方法
 */
use App\Models\Author;
$authors = Author::all(); // all()でも取得できる
```

# `get`と`all`どっちを使ったらいいの？？

`all`も`get`と同様の機能であるが、全部取得するときは`all`メソッドの方がよく使われる印象(著者も`all`を好んで使っています、処理内容が`all`(=全部)と分かりやすいから)。

特段の指定がないときは`all`メソッドを使うことを僕はお勧めしますっ！
自作難解プログラミング言語「DigFiles」がチューリング完全であることを証明してみせる！（Brainfuckインタプリタの実装）

# はじめに
前に「[フォルダ&ファイル構成を活用する自作の難解プログラミング言語「DigFiles」を作ってみた](https://qiita.com/yamaserif/items/d9f28fdf22465199dcb4)」という記事を書いたのですが、前回は言語仕様などしか書いていなかったので、今回は少し踏み込んでこの言語がチューリング完全[^1]であることを証明してみたいと思います。

# 方法
チューリング完全の証明方法は[難解プログラミング言語のまとめWiki](https://esolangs.org/wiki/Computational_class)にいくつか書いてあります。
その中で今回は以下の方法を使いたいと思います。[^2]
> Say you have a language K whose computational class is known. (A common value for K is Brainfuck, which is known to be Turing-complete.) You also have a language Q whose computational class is in question, and you want to show that it is computationally equivalent to K.
...
**Simulation**
If an interpreter for K can be implemented in Q, then Q can solve at least as many problems as K can.

「計算量が既に知られている**言語K**があるとする。(**K**の一般的な値は[Brainfuck](https://esolangs.org/wiki/Brainfuck)で、これはチューリング完全であることが知られている。) また、計算クラスが疑問な**言語Q**があり、これが**K**と計算上等価であることを示したいとする。
...
**シミュレーション**
**K**のインタプリタが**Q**に実装できれば、**Q**は少なくとも**K**と同数の問題を解くことができる。[^3]」

ということで、DigFilesでBrainfuckのインタプリタを実装してみます。

# 実装方針
実装の考え方としては、Brainfuckにて入力されたコードを各文字で分岐させてあげて、それぞれの命令と同等の処理を実行させれば良いことになります。

### 分岐の実装
DigFilesには分岐自体の命令はありませんが、loopコマンドを使用することで分岐の動作を行わせることが可能です。

ただし、本来繰り返し処理用の命令であるため、色々工夫する必要があります。

例えば、このloopコマンドは「2つの変数が同値でない間」に処理を行うため、そのままの状態でBrainfuckの文字と値を比較してもノットイコールでの判定しか出来ません。

従って構成としては、条件が不成立時にセットされるフラグを準備しておき、そのフラグにて再度判定をかける形で実装していきたいと思います。

その他にも、ループから抜け出すための値管理など色々丁寧に実装していく必要があります。

### []の実装
基本的には、入力されたBrainfuckコードの実行箇所を表す変数の値を適宜書き換えることで実装できます。
ただし、Brainfuckの命令である[]はコード上でネストされている可能性が考えられるため、移動先は注意する必要があります。
今回はDigFilesの記憶領域に変数名を連番で扱うことで擬似的なスタック領域として扱い、[の出現位置を管理していけば良さそうです。

### ><+-.,の実装
これはわりと単純な命令ですので、そのままDigFilesの操作とある程度対応付けられそうなので、愚直に実装できそうです。
|Brainfuck  |DigFiles  |
|---|---|
|>  |addコマンドにて「ポインタ変数」を+1する[^4]  |
|<  |addコマンドにて「ポインタ変数」を-1する[^4]  |
|+  |addコマンドにて「*ポインタ変数」を+1する[^5]  |
|-  |addコマンドにて「*ポインタ変数」を+1する[^5]  |
|.  |outコマンドにて「*ポインタ変数」にセットされている文字を出力する[^6]  |
|,  |inコマンドにて「*ポインタ変数」に入力された文字をセットする[^6]  |

※実際には変数idは数値の形ですが、ここではわかりやすく日本語で記述します。

# 実装
上記を踏まえて実装した結果が以下のコードになります。[^7]
[Githubのページ](https://github.com/yamaserif/DigFiles/tree/main/example/Brainfuck_interpreter)

正直、わりとクソコードだと思います。
単純にファイル名とかフォルダ名でコーディングしようとすると、名前の変数を割り当てるのがめちゃくちゃめんどくさくて、行き当たりばったりの命名になってしまっている部分があります。
（とはいえ、DigFilesの言語方針通り、細かくメソッド分けはされているので予定通りとも言えるのかもしれませんが…）

また、今回盲点だったのがフォルダ構成のネストが深くなっていったせいで、途中フォルダ名の文字数に制限がかかってしまいました。
Windowsはパスの長さに細かい制限があるの忘れていました…[^8]

# 最後に
このコードを実行してもらうと分かるのですが、処理速度激遅です。

Brainfuckのインタプリタを、DigFilesのインタプリタで動かしている関係上ある程度仕方のないことではありますが、ネット上のオンラインコンパイラで1秒もかからない処理が2分30秒位かかったりします。
デバッグ時に無限ループ入っているのか処理に時間がかかっているのかの判断に困ったりしました。

まぁ、兎にも角にもとりあえず当初の目的である、チューリング完全の証明ができたのでひとまず安心しました。
あぁ、よかった よかった。


[^1]: チューリング完全の詳しい意味については省略しますが、ざっくり「高級言語と同等の計算能力を持っていること」と捉えてもらって大丈夫です。
[^2]: ReductionやTranslationでも証明できそうですが、今回は最終的に成果物として形が残せるという理由でSimulationを選定しました。
[^3]: この形式の証明には潜在的な問題ℒがあると示されていますが、今回は当てはまらなそうでしたので無視します。
[^4]: DigFilesでは値領域の初期値はランダム値となっているため、適宜0に初期化します。
[^5]: 一応、0~255の値を取るように最大値、最小値で値がループするように仕込んでおきます。
[^6]: 一応文字コードは異なりますが、DigFilesで使用されているUTF-8はその歴史的経緯からASCIIに互換性があるため問題ありません。
[^7]: 入力値はBrainfuckコードの終わりを認識するため、コードの末尾に「/」を付けています。
[^8]: 今よく考えたら「subst」使えばもうちょっとフォルダ名粘れたっちゃあ粘れたな…
PowerShellでAndroidとかのTimePickerを実装してみた。

# はじめに

Androidとかで使われているアナログの時計盤みたいな
時刻入力コントロールをPowerShellでも実装してみたいと思い立って
やらかしてみました。

## 製作環境

- Windows 10,11
- PowerShell 5.x

## 画面イメージ

### 時間入力モード

![image_hour.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298004/23cf5ab9-5999-8ba6-6d87-a695962129ae.png)

### 分数入力モード

![image_minute.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298004/f76ae3fb-4102-4ef0-b70d-76d92d7bf912.png)

## つかいかた

呼び出し方の例です。
コンストラクタで位置指定できます。

```powershell
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
. .\TimePicker.ps1
$tp = New-Object TimePicker(25,5)
$form = New-Object System.Windows.Forms.Form
$form.ClientSize = New-Object System.Drawing.Size(250,250)
$form.Controls.Add($tp)
$form.ShowDialog() > $null
```

## ソース

GitHubに置いてます。
https://github.com/imoimo2009/TimePicker
デバッグ・テクニック


printデバッグをしていると、出力が多すぎて困る事がある。
単にif文を入れて済めば良いが、それでは制御しきれない事も多々ある。

その様なケースでの、幾つか対処法を紹介する。

# note

* 言語は C++ を想定しているが、他の言語でも流用は出来るはす。


# エラー発生の前でのみデバッグ

## 状況設定

* 何度目かの呼び出しで、エラーが発生する。
  * 他の関数を挟んで呼び出しているため、呼び元(ループ側)での制御はしずらい。
* エラーが発生する少し前の状態を知りたい。
```cpp
void fn_3()
{
  ...
  Trace(data); // 変更前の、この時点での情報が欲しい。
  ...          // data が変更される。
  data.foo();  // ここでエラーが発生する。
}

void fn_2(){ fn_3(); }
void fn_1(){ fn_2(); }

void fn()
{
  for(...){
    fn_1();
  }
}

```
## 解決策

関数内stasic変数で、関数の呼び出し回数が分かるようにし、
エラー発生時点での関数の呼び出しが何回目かを記録する。
```diff_cpp
void fn_3()
{
+ static int debug_counter = 0;
+ ++debug_counter;

  ...
+ Trace(debug_counter); // エラー発生のタイミングを確認
  data.foo();           // エラー発生時に、何らかの方法で処理を止める。
}
```

何度目の関数呼び出しでエラーが発生するかが分かったら、
そのタイミングでのみ、Traceさせる。
```diff_cpp
void fn_3(){
+ static int debug_counter = 0;
+ ++debug_counter;

  ...

+ if ( counter == 193 ) { // 事前に確認した値。
    Trace(data);
+ }

  ...
  data.foo();
}
```


# 継承先でのデバッグ

## 状況設定

以下の様に、ID番号を共通の親クラスで管理しているとする。
```cpp
class Element {
public:
  void SetID( const int id ) { m_id = id; }
  ...
private:
  int m_id{};
};

class Impl_A : public Element {...};
class Impl_B : public Element {...};
class Impl_C : public Element {...};
```

`Impl_A` での m_id の値が可怪しいので、`SetID` のタイミングでデバッグをしたいが、
`SetID` にトレース文を入れると、`Impl_B`,`Impl_C` の `SetID` でもログが出てしまう。

## 解決策

* SetID を仮想関数にし、Impl_A でのみオーバーライドをする。
  * 実装は、親の関数を呼ぶようにする。
```diff_cpp
class Common {
public:
-  void SetID( const int id ) { m_id = id; }
+  virtual void SetID( const int id ) { m_id = id; }
  ...
private:
  int m_id{};
};

class Impl_A : public Common {
+   void SetID( const int id ) override {
+     Trace( id );
+     Common::SetID(id);
+   }
  ...
};
class Impl_B : public Common {...};
class Impl_C : public Common {...};
```


# 特定呼び出しからのデバッグ

## 状況設定

特定の場所から呼ばれた時のみ、デバッグをしたい。

```cpp
void fn_3( ... )
{
  Trace(...); // fn_A から呼ばれた時のみ、Trace したい。
}

void fn_2( ... ){ fn_3( ... ); }
void fn_1( ... ){ fn_2( ... ); }

void fn_A() { fn_1( ... ); }
void fn_B() { fn_1( ... ); }
void fn_C() { fn_1( ... ); }
```

引数にフラグを追加する、では、変更量が多くて大変。
* オーバーロードが有ると、処理を変えてしまう可能性もある。
```cpp
void fn_3( ..., const bool debug_flag = false )
{
  if ( debug_flag ) {
    Trace(...); // fn_A から呼ばれた時のみ、Trace したい。
  }
}

void fn_2( ..., const bool debug_flag = false )
{
  fn_3( ..., debug_flag );
}
void fn_1( ..., const bool debug_flag = false )
{
  fn_2( ..., debug_flag );
}

void fn_A() { fn_1( ..., true ); }
void fn_B() { fn_1( ... ); }
void fn_C() { fn_1( ... ); }
```

## 解決策
コードをコピーし、同じ実装の、別の関数を作れば良い。

```diff_cpp
void fn_3( ... )
{
}

void fn_2( ... ){ fn_3( ... ); }
void fn_1( ... ){ fn_2( ... ); }

+namespace ForDebug {
+
+void fn_3( ... )
+{
+  Trace(...);
+}
+
+void fn_2( ... ){ fn_3( ... ); }
+void fn_1( ... ){ fn_2( ... ); }
+
+} // ForDebug

-void fn_A() { fn_1( ... ); }
+void fn_A() { ForDebug::fn_1( ... ); }
void fn_B() { fn_1( ... ); }
void fn_C() { fn_1( ... ); }
```
* ビルドが通らない場合は、関連コードを片っ端からコピーして持ってくる。
* static 変数が絡む場合は、処理が変わってしまう事に留意。

# おまけ

* 通常は使用を避けるべき、コードのコピーやstatic変数だが、この様な場合は便利に使え。る
  * デバッグ用の使い捨てコードなので、諸々のデメリットも気にしなくて済む。
* デバッグ用のコードで使う識別子は、うっかり Push してしまった場合に備えて、
それと分かる様な名前にしておくとベター。
DockerでFlask環境構築【Python】

## ディレクトリ構成
```:ディレクトリ構成
└─VoiceEmotion
    ├─Dockerfile
    ├─docker-compose.yml
    └─app
        ├─requirements.txt
        └─app.py
```
## Dockerfile
```Dockerfile
# pythonのバージョンは任意
FROM python:3.8

WORKDIR /usr/src/app
ENV FLASK_APP=app

COPY /app/requirements.txt ./

RUN pip install --upgrade pip
RUN pip install -r requirements.txt
```
**FROM**
ベースになるコンテナイメージの指定

**WORKDIR**
コンテナ内の作業ディレクトリを指定

**ENV**
環境変数の設定
必要に応じて使う．

**COPY**
イメージを構築するときに、ローカル環境からコンテナ内にファイルをコピーして設置する

**RUN**
コンテナ内のシェルコマンドを実行

## docker-compose.yml
```docker-compose.yml
version: "3"
services:
  app:
    build: .
    ports:
      - "5001:5000"
    container_name: app
    volumes:
      - ./app:/usr/src/app
    command: flask run --host=0.0.0.0
```

**version**
``compose``ファイル形式のバージョン
バージョンによって書き方が異なるようです
- [docker-compose.ymlの書き方について解説してみた](https://qiita.com/yuta-ushijima/items/d3d98177e1b28f736f04)
- [バージョンについて](https://docs.docker.jp/compose/compose-file/compose-versioning.html)

**service**
全体を構成するコンテナの設定

**app**
コンテナ名

**build**
Dockerfileを含むディレクトリパスを指定します。

**ports**
ホスト側ポートとコンテナ側ポートのマッピングを指定する．
`` [host_port]:[container_port]``

composeファイルの書き方でよさげのものがあったので引用します。
[引用元](https://ai-can-fly.hateblo.jp/entry/summary-of-docker-compose-for-beginners)
```docker-compose.yml
version: '3.8'

services:
  [service_name]:
    build: [context_path]
    image: [image_name]:[tag_name]
    container_name: [container_name]
    command: [command]
    environment:
      [variable_name]: [value]
    volumes:
      - [volume_name]:[container_directory_path]:[mode]
      - [host_directory_path]:[container_directory_path]:[mode]
      - type: volume
        source: [volume_name]
        target: [container_directory_path]
      - type: bind
        source: [host_directory_path]
        target: [container_directory_path]
    networks:
      - [network_name]
    ports:
      - '[host_port]:[container_port]'
    tty: [boolean]
    restart: [restart_policy]
    depends_on:
      - [other_service_name]
  [other_service_name]:
    ...

volumes:
  [volume_name]:

networks:
  [network_name]:
```

## requirements.txt
このファイルを作成して、パッケージ情報を記載します。
Dockerfile内にある``RUN pip install -r requirements.txt``コマンドにより
``requirements.txt``ファイル内にあるパッケージを一括インストールすることができます。
```requirements.txt
flask==2.0.1
```



## app.py
```python:app.py
from flask import Flask

app = Flask(__name__)

@app.route("/")
def index():
    return "index page"
```

## 実行
以下のコマンドを実行して、[localhost5001](http://localhost:5001)にアクセスします
```
docker-compose up
```

``index page``という文字が表示させていれば成功です。

## 参考
- [DockerでFlaskを実行するコンテナを作る](https://gray-code.com/blog/flask-on-docker/)
- [Composeファイルのバージョンとアップグレード](https://gray-code.com/blog/flask-on-docker/)
- [【Docker】初心者のためのDocker Composeまとめ](https://ai-can-fly.hateblo.jp/entry/summary-of-docker-compose-for-beginners#ports-%E3%83%9D%E3%83%BC%E3%83%88)
- [Compose specification](https://docs.docker.com/compose/compose-file/)
- [docker-compose.ymlの書き方について解説してみた](https://qiita.com/yuta-ushijima/items/d3d98177e1b28f736f04)
Ubuntu20.04でTeX環境構築

# はじめに
Ubuntu20.04においてTeXの環境構築を行う記事です．躓いている方の手助けになれば幸いです．

# TeXLiveのインストール
aptパッケージでもインストールは可能ですが，古いバージョンの可能性があります．そのため直接インストーラをダウンロードしそれを実行する形でインストールすることを推奨します．

### インストーラのダウンロード
```
$ wget http://mirror.ctan.org/systems/texlive/tlnet/install-tl-unx.tar.gz
```

### インストーラの解凍
```
$ tar xvf install-tl-unx.tar.gz
```

### インストーラの実行
```
$ cd install-tl-20220626
$ sudo ./install-tl -no-gui
```
ディレクトリ名はダウンロードした日付によって変わるので適宜読み替えてください．
install-tlをroot権限で実行することでインストーラが起動します．

```
======================> TeX Live installation procedure <=====================

======>   Letters/digits in <angle brackets> indicate   <=======
======>   menu items for actions or customizations      <=======
= help>   https://tug.org/texlive/doc/install-tl.html   <=======

...略...

Actions:
 <I> start installation to hard disk
 <P> save installation profile to 'texlive.profile' and exit
 <Q> quit

Enter command:
```
Iを入力しインストールを開始します．ファイルサイズが膨大なためダウンロードには時間がかかります．気長に待ちましょう．
デフォルトで`/usr/local/texlive`に諸々のファイルがコピーされます．

### パスの追加
今回は最新版の2022が入ったようですので2022の中のbinにパスを通します．
`~/.bashrc`に以下を追記します．
```
export PATH="$PATH:/usr/local/texlive/2022/bin/x86_64-linux"
```


# TeXworksのインストール
TeXの便利な開発環境TeXworksをインストールします．
こちらについてはTeXLiveと違いaptパッケージでインストールしていただいて結構です．
```
$ sudo apt install texworks
```

# テスト
きちんと動作するか確認しましょう．まずはTeXworksを実行します．
```
$ texworks
```
エディターで以下を打ち込みます．
```
\documentclass[a4paper]{jarticle}

\begin{document}

Hello \TeX world! 

\end{document}
```
緑の矢印ボタンを押してPDFを生成してみましょう．もしボタンの右側で`pLaTeX(ptex2pdf)`が選択されていなければ選択しましょう．
別ウインドウが開きPDFが表示されたら成功です．お疲れ様でした．
[iOS]設定アプリで許可（位置情報・カメラアクセスなど）を変更してから該当アプリに戻るとクラッシュする

どうやらiOS側のバグ（仕様？）である模様。。。

参考

[Stack Over Flow](https://stackoverflow.com/questions/12652502/app-killed-by-sigkill-when-changing-privacy-settings)
[Developer Forums - App crashes when changing privacy settings](https://developer.apple.com/forums/thread/64740?answerId=277988022#277988022)
２進数と８進数・１６進数の基数変換

８進数、１６進数は２進数で一桁を表すとそれぞれ３桁、４桁になる。
それを利用して１０真数に変換する。

# 例　1101.01を変換
８真数なので３桁ごとに分ける。なので
１と101と01に分ける。

## ８進数の場合
１は１
１０１は３桁目は４と１桁目は１なので５
０１０は２桁目は２
15.2になる。

## 16進数の場合
4桁ごとに分ける。なので
1101になる
４桁目は８
３桁目は４
１桁目は１　
１３になるが１６真数なのでDになる。

０１になる。
３桁目が４
なので４になる。
これは１６進数で表せるのでそのまま

D.４になる。

# 逆に２進数に変換する
15.2になる。
１は００１
５は１０１
２は０１０
で
00```1101.010```になる。

１６進数の場合
D.4
```1101.010```0になる。
２つとも同じ結果になった。

# 気づき
たくさん訓練しないと簡単にはできないような感じがする。

出典 キタミ式イラストIT塾　基本情報技術者　令和０３年
【Flutter】画面のスタート時にダイアログを表示する方法

# はじめに
Flutterで画面遷移した際や、アプリを起動した際など、画面の最初にダイアログを表示したいと思い調べてみたんですが、日本語の記事を見つけられなかったので記事にします

# ステップ１
ダイアログを呼ぶ関数を用意する
```dart:dialog.dart
Future<void> _showStartDialog() async {
    return showDialog<void>(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          title : Text('タイトルテキスト'),
          content: Text("コンテントテキスト"),
          actions: <Widget>[
            TextButton(
              child: Text('OK'),
              onPressed: () {
                Navigator.of(context).pop();
              },
            ),
          ],
        );
      },
    );
  }
```
# ファイルのinitStateで呼び出す
```dart:dialog.dart
void initState() {
    super.initState();
    WidgetsBinding.instance!.addPostFrameCallback(
            (_) => _showStartDialog()//
    );
  }
```

この書き方については[こちら](https://qiita.com/Rwf-9DH3/items/b681c68b06e70b02ae8d)の記事に書いてあります。

これで以上です！おつかれさまです！
単価診断の2,000人の回答をgoogle data studioで公開してみた

ISSUEサービス内に蓄積された単価診断のデータを公開しました！

このレポートを確認するにはこちらからアクセスしてください↓
[ISSUEの業務委託単価診断レポート](https://datastudio.google.com/reporting/fce2ed80-c0ec-4b3b-9b36-6650bee09359)
![](https://storage.googleapis.com/zenn-user-upload/c7cee9f5f6e7-20220626.png)

## おすすめの使い方
ぜひ、「[ISSUEの業務委託単価診断レポート](https://datastudio.google.com/reporting/fce2ed80-c0ec-4b3b-9b36-6650bee09359)」を**ブックマーク**していただければ幸いです。毎日回答数が蓄積されていくにつれてより正確な単価が算出されていくようになります。どなたでも確認できるように常に公開しておきます。

## 経緯
2021年末に単価診断機能をリリースしました。おかげ様で約2000人の回答が得られました。一方で副業やフリーランスになる方々の単価設定はまだばらつきがあるように感じます。回答結果を参考にして、単価の目安を把握、また次の段階の単価交渉のタイミングを見極める判断材料になれば幸いです。


# 単価表のインサイト

## 4,000 ~ 5,000円の単価層が最も多い
診断を回答された方々の中で最も多かったのが4,000 ~ 5,000円の単価層になります。
![](https://storage.googleapis.com/zenn-user-upload/e92faa0b8850-20220626.png)

診断を受けている方々の5割以上が実務経験年数が3年以上であるためだと思います。
1 ~ 2年と実務経験が比較的浅い層よりも、年次を重ねた方の方が力試しや「副業」をする余裕、また独立に意識を向かうので、単価への関心が高まりこのような結果になっているのかもしれません。
![](https://storage.googleapis.com/zenn-user-upload/6297f055cbf1-20220626.png)

## 時給単価10,000円を超えるエンジニアは約1%
これはヒアリングした際にも、10,000円/時給を超えるエンジニアの割合は1%ほどだったのでかなり再現度高く診断機能を作れているのではないかと思います。時給が10,000円を超える方は「国内でも特定の技術分野をリードしている(ユーザーコミュニティの中核、書籍の販売等)」「OSSへのコントリビュート経験」「10年以上の実務経験がある」「大企業に勤めている・いた」などのワードが多く出てきました。また特定の専門領域(データサイエンティストなど)で需要が高く価格が高騰しているケースもあります。
![](https://storage.googleapis.com/zenn-user-upload/9104b03ffed8-20220626.png)

# 上の単価を目指すには

※やや単価が高く推移しているので参考程度にお考えください

## 時給単価6,000円を超えるには？
6,000円まではプレイヤーとしての経験で十分にたどり着ける印象です。「リード経験」「専門領域は持ちつつ、ある程度全レイヤー見れる力」「ミドルベンチャー以上での就業経験」など目を引くような経歴や役職の経験があると到達しやすいようです。
![](https://storage.googleapis.com/zenn-user-upload/b99a133d59ce-20220626.png)


## 時給単価7,000円を超えるには？
平均時給単価7,000円を超えた回答としては、「CTO・技術顧問経験」「OSSコントリビュート」「エンジニア採用活動」などプレイヤー・マネージャー両方の特徴が見て取れました。開発組織の規模が多いと役職やマネジメント系の業務内容は年次的な要素もあると思うので、20代でもこの単価を目指したいのであればプレイヤー要素(「OSSコントリビュート」「書籍発行」「メディアで取り上げてもらう」)で攻めていくのもいいかと思いました。
![](https://storage.googleapis.com/zenn-user-upload/5f7d53ecd970-20220626.png)

## 分析リクエストお待ちしています！
今回はさっと作ったものを公開しているので、この部分の考察がもっと欲しい、もっとフォーカスして欲しいデータがあるなどありましたら、コメントいただけるとありがたいです！随時追加して行きます！

## 最後に
現状DBに眠っているだけのデータだったので、今後の業務委託市場役立てばと思い公開しました。また単価の相談などはセンシティブな部分でなかなかオープンにしづらいところもあります。そんな時は[ISSUEの業務委託単価診断レポート](https://datastudio.google.com/reporting/fce2ed80-c0ec-4b3b-9b36-6650bee09359)をみて参考にしていただけれと思います。

## 単価診断はこちら
https://i-ssue.com/surveys
【Rails】orderメソッドが効かないとき


1対多のアソシエーションの場合の並び替えで躓いたのでメモφ(´･ω･｀)ﾒﾓﾒﾓ

今回は、記事に対するコメントを新着順で並び替えです。

まず、新着順にするために下記のように、
コントローラーにorder(created_at: :desc)を追記しました。
しかし、並び替えされず・・・

```ruby:app/controllers/post_controller.rb
def show
  #~~省略~~
  @comment = Comment.new
  @comments = @post.comments.order(created_at: :desc)
end
```

解決方法
----

**1) postモデルに-> { order(created_at: :desc) }を追加**
※dependent: :destroyの前に置くとエラーになりました。
```ruby:app/models/post.rb
 class Post < ApplicationRecord
  belongs_to :user
  has_many :comments, -> { order(created_at: :desc) }, dependent: :destroy
  #~~省略~~
end
```
**2) commentモデルにoptional: trueを追加**
```ruby:app/models/comment.rb
class Comment < ApplicationRecord
  belongs_to :user
  belongs_to :post, optional: true
 #~~省略~~
end
```
**3) Postコントローラーにincludes(:comments)を追加**
```ruby:app/controllers/post_controller.rb
def show
  #~~省略~~
  @comment = Comment.new
  @comments = @post.comments.includes(:comments)
end
```

以上の手順でコメントを新着順に並び替えることができました！
form_withのlocal trueについて

form_withのlocal trueについて

まずなぜlocal trueとするのかというと同期通信にしたいから。

local trueを追記していないとajax通信、つまり非同期通信を行うためサーバにform_withの内容が送られず
null falseなどでエラー文を表示させるはずが同期通信でないために表示されない事象が起きる。

検証ツールで確認してもTypeがxhrとなっててAjax通信を行なっていることがわかる。
![696D3B47-6495-4B1D-9411-A1AA89E04FEB_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2591297/ed6d379d-e253-a0ec-bc5c-a9b161dd4bd8.jpeg)

ちなみにRails6.1以降はform_withはデフォルトで同期通信らしいので、　ajax通信を行いたいときは、```config/application.rb```に```config.action_view.form_with_generates_remote_forms = true```を追記する。

xhrとはXMLHttpRequest　xがajaxの部分。

参考記事　https://qiita.com/kakudaisuke/items/e032c7705db00e8081dc?utm_campaign=popular_items&utm_medium=feed&utm_source=popular_items
Haskellで各種ソートを実装してみる

# Haskellとは

Haskellとは純粋関数型プログラミング言語の代表格である。
関数型という特徴故に普段我々が慣れ親しんでいる手続き型とはパラダイムが大きく異なるため習得には、多少の苦労が必要。代表的な言語特性としては、変数の再代入禁止・関数のパターンマッチング・遅延評価(無限リストの実現)などがある。

公式サイト : [https://www.haskell.org/](https://www.haskell.org/)

# 選択ソート

### 特徴

* 最悪計算量 $O(n^2)$
* 安定でない

### ソースコード

```haskell
selectionSort :: (Ord a) => [a] -> [a]
selectionSort [] = []
selectionSort [x] = [x]
selectionSort xs =
  min:selectionSort [x | x <- xs, x /= min] -- 1
  where min = minimum xs -- 2
```

### ソースコード解説

1. 与えられた配列の最小値を省いた配列をselectionSortに渡し、その配列の先頭に最小値を挿入
1. 配列から最小値を取り出し、値をminに格納


# バブルソート

### 特徴

* 最悪計算量 $O(n^2)$
* 安定

### ソースコード

```haskell
bubble :: (Ord a) => [a] -> [a]
bubble [] = []
bubble [x] = [x]
bubble (x:y:xs) -- 1
  | x < y = x:bubble (y:xs) --  2
  | otherwise = y:bubble (x:xs) -- 3

bubbleSort :: (Ord a) => [a] -> [a]
bubbleSort [] = []
bubbleSort [x] = [x]
bubbleSort xs = bubbleSort (init r) ++ [last r] -- 4
  where r = bubble xs -- 5
```

### ソースコード解説

1. 先頭と2番目の要素をx,yに束縛
1. yがxよりも大きい場合はxとyを入れ替えない
1. それ以外の場合はxとyを入れ替える
1. rの最後の要素以外をbubbleSortに渡し、得られた配列に最後の要素を追加
1. bubble関数で処理された配列をrに格納(rの最後の要素は配列中の最大値になっている)

# クイックソート

### 特徴

* 最悪計算量 $O(n^2)$
* 安定でない

### ソースコード

```haskell
quickSort :: (Ord a) => [a] -> [a]
quickSort [] = []
quickSort [x] = [x]
quickSort (x:xs) = -- 1
  quickSort l ++ [x] ++ quickSort r -- 2
  where l = filter ( <= x) xs -- 3
        r = filter ( > x) xs -- 4
```

### ソースコード解説

1. 先頭の要素をxに束縛
1. lを渡して得られた配列をxの左、quickSortにrを渡して得られた配列をxの右に結合
1. xを除いた残りの配列のうちx以下のものを配列lに格納
1. xを除いた残りの配列のうちxより大きいものを配列rに格納

# マージソート

### 特徴

* 最悪計算量 $O(nlogn)$
* 安定

### ソースコード

```haskell
marge :: (Ord a) => [a] -> [a] -> [a]
marge xs [] = xs
marge [] ys = ys
marge (x:xs) (y:ys) -- 1
  | x < y = x:marge xs (y:ys) -- 2
  | otherwise = y:marge (x:xs) ys -- 3

margeSort :: (Ord a) => [a] -> [a]
margeSort [] = []
margeSort [x] = [x]
margeSort xs = marge (margeSort l) (margeSort r) -- 4
  where l = take half xs -- 5
        r = drop half xs -- 6
        half = length xs `div` 2 -- 7
```

### ソースコード解説

1. 1つ目の配列の先頭の要素をxに束縛、2つ目の配列の先頭の要素yに束縛
1. yがxよりも大きい場合は、margeに1つ目の配列の残りの部分と2つ目の配列を渡し、得られた配列の先頭にxを挿入
1. それ以外の場合は、margeに1つ目の配列と2つ目の配列の残りの部分を渡し、得られた配列の先頭にyを挿入
1. margeにmargeSortに配列lと配列rをそれぞれ渡したものを渡す
1. 与えられた配列を半分に分割し、前部分を配列lに格納
1. 与えられた配列を半分に分割し、後ろ部分を配列rに格納
1. 配列の長さを2で割ったものをhalfに格納(\`div\`はdivの中置記法文法)

# あとがき

上記のコードは、筆者がHaskellの学習のために浅い知識でとりあえず動くように作ってみたコードです。よって、蛇足な箇所やHaskellの特性を生かし切れていない部分も見受けられるかもしれませんが、何卒ご了承ください。

# これからHaskellを学ぶ方へ

[すごいHaskellたのしく学ぼう！](https://www.amazon.co.jp/dp/B009RO80XY/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)
巷で「すごいH本」としてよく知られているHaskell入門書の定番。ポップなタイトルとは裏腹に割と本格的（言語特性的に仕方がないかも?）で網羅的。
【paiza】【Ruby】paizaの標準入力について、入力値を可変させてデバッグする方法

paizaの解答欄では標準入力が一つしか与えられず、説明文の中で下記のように記載されていましたが、入力値を変える方法が分からず苦労したので、まとめてみました。
_「複数の与えられる入力でテスト致しますので、 サンプル入力だけでなく入力値を可変させてデバッグしていただく事をお勧めいたします。」_

かなり基礎的なところでしたが、私はVSCodeで回答とinputファイルをそれぞれ作成した上でファイルをリダイレクトして標準入力したところ、上手くいきました。
(リダイレクトは、rubyというよりはlinux?)

~~~ruby:example.rb
N = gets.to_i
ans = []
N.times do
  ans << gets.chomp.split.map(&:to_i)
end
print ans
~~~

~~~input.txt
4
13 12
11 12
1 1
4 4
~~~

~~~ターミナル
$ ruby example.rb < input.txt
~~~

【参考】
https://www.kenschool.jp/blog/?p=1143

初学者のため、不備等あればご連絡ください。
【PHP】【JavaScript】PHPで簡易WebAPI作成 〜 JavaScriptで取得しブラウザに表示させるまで

バックエンド：PHP
フロントエンド：JavaScript
で開発する場合に、つなぎ込みの部分がよく分かっていなかったため学習して備忘録として残しました。
つなぎ込みの部分の理解が目的であるため、APIの内容はかなりシンプルです。

# ① 簡易WebAPIの実装

```php:api.php
<?php
$api["status"] = "PHPで作ったWebAPIです。";

// 配列をjson形式にデコードして出力
print json_encode($api);
```

# ② JSでAPIを呼び出す

```JavaScript:index.js
const TEST_API = "http://localhost:8000/api.php";

async function callApi() {
  const res = await window.fetch(TEST_API);
  const tests = await res.json();
  console.log(tests);
}

callApi();
```

# ③ HTMLファイルの「src=」でJSファイル名を指定することにより、JSを連携させる

```html:index.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <title>Document</title>
  </head>
  <body>
    <p>Chrome DevTools で console を開いてね</p>
    <script src="index.js"></script>
  </body>
</html>
```

JavaScriptでWebAPIのデータを取得する方法はたくさんありますが、今回はfetchメソッドを使用しました。
fetchメソッドの詳細については[こちら](https://developer.mozilla.org/ja/docs/Web/API/Fetch_API/Using_Fetch
)を参考にしてみてください。

# ④ ビルトインサーバを立ち上げ、ブラウザのコンソールで確認

```
php -S localhost:8000
```


![スクリーンショット 2022-06-27 11.01.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/985164/46bd708a-a788-a4f4-8265-94f133133f4c.png)

このように、APIで実装した内容がブラウザのコンソールに反映されていることが確認できました！

- 参考：[PHPで簡単なWebAPIを実装してみる【初心者向け】](https://note.com/kazztech/n/ndb3a5468f299)

# ⑤ 補足 async/awaitについて

一言で言うと「実行できる時に実行する」です。
DBの処理など、時間のかかるものを待っていたら表示が遅くなってしまう（ユーザーを待たせてしまう）ので、上から順に処理を実行するのではなく、実行できるものから実行していくことで効率良く処理を進めることができます。

- 参考：[非同期関数](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/async_function)
【Laravel9】Policyを使って認可を与える

## Laravelで認可を与える方法
大きく2つの方法があり、`Gate`を使う方法と`Policy`を使う方法がある。

### Gate
特定のモデルに関連していないユーザーのアクションに関してアクセス制限を行う。

### Policy
ある特定のモデルに対して行うアクションに関してアクセス制限を行う。
※今回はこちらのPolicyを使って行う

## 前提
- Userモデル、Postモデルは既に作成している
- laravel9

## PostPolicyファイルを作成する


```
$ php artisan make:policy PostPolicy
Policy created successfully.
```
`make:policy`コマンドは、空のポリシークラスを生成する。
リソースの表示、作成、更新、削除に関連するポリシーメソッドのサンプルを含んだクラスを生成する場合は、
下記のようにコマンドの実行時に--modelオプションを指定する。

```
$ php artisan make:policy PostPolicy --model=Post
Policy created successfully.
```

```
namespace App\Policies;

use App\Models\User;
use App\Models\Post;
use Illuminate\Auth\Access\HandlesAuthorization;

class PostPolicy
{
    use HandlesAuthorization;
    
    /**
     * Determine whether the user can view any posts.
     *
     * @param  \App\User  $user
     * @return mixed
     */
    public function viewAny(User $user)
    {
        //
    }

    /**
     * Determine whether the user can view the post.
     *
     * @param  \App\User  $user
     * @param  \App\Post  $post
     * @return mixed
     */
    public function view(User $user, Post $post)
    {
        //
    }
　　 // 以下省略
```

## Policyを利用してアクセス制限をかける準備をする
今回は投稿の編集を行うため、updateメソッドに記載をする。

```
class PostPolicy
{
    use HandlesAuthorization;

    public function update(User $user, Post $post)
    {
        return $user->id === $post->user_id;
    }
}
```

## 作成したPolicyの情報をAuthServiceProvider.phpに登録する
作成したPolicyの情報はAuthServiceProvider.phpに登録を行う必要がある。
登録を行うことでPostモデルとPostPolicyが紐づけられる。

```
    protected $policies = [
        Post::class => PostPolicy::class,
    ];
```

## authorizeメソッドを利用して制限をかける
authorizeメソッドを記述することでPolicyでアクセス制限を行うことができる。
updateメソッドに記載。

最初の引数(update)がPostPolicyファイル内に記述したupdateメソッドに対応する。
2番目の引数には、postモデルの変数$postを指定する。
```
public function update(Postrequest $request, $id) {

    $this->authorize('update', $post);
    $post->save();
    return view('posts.update');
}
```

## viewにてcanを使ってログインユーザーのみに編集ボタンを出す
```
@can('update', $post)
    <td><a class="btn btn-info btn-sm" href="{{ url('posts/'.$post->id .'/' .'edit') }}">編集</a></td>
@endcan
```
【Windows】Bginfo設定

### Bginfoダウンロード先

https://docs.microsoft.com/en-us/sysinternals/downloads/bginfo

### Bginfoインストール
ダウンロードしたBginfoのファイルを任意の場所に保存し、Bginfo.exe または Bginfo64.exe を起動。

### Bginfoをログイン時に起動するよう設定
1. ダウンロードして展開した「Bginfo」フォルダをC直下に保存
2. Bginfo.exe または Bginfo64.exe を起動
3. デスクトップに表示させたい内容を編集し[File]-[Save As...]で編集内容をbgiファイルとして保存する
4. C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp\Bginfo.bat を作成
```cmd:Bginfo.bat
@echo off
"C:\BGInfo\Bginfo.exe" "C:\BGInfo\Bginfo.bgi" /TIMER'00 /nolicprompt /silent
```
VR技術者認定試験に出てくる「〇〇効果」まとめてみた

VR技術者認定試験を勉強中です！
過去問に出てくる `〇〇効果` という用語を集めてみました。

あくまで、個人の学習で気づいたものを集めただけで、網羅されているわけではありませんので、ご了承ください。


# 顔倒立効果（サッチャー錯視）
歪んでいる顔でも顔の上下を逆さまにすると歪みに気が付きにくい現象のこと。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/17a7dd2b-191c-2adb-12ac-7e1efc8c5419.png)
※引用: [Wikipedia / サッチャー錯視](https://ja.wikipedia.org/wiki/%E3%82%B5%E3%83%83%E3%83%81%E3%83%A3%E3%83%BC%E9%8C%AF%E8%A6%96)


# 腹話術効果
音源定位が視覚で知覚された位置によってバイアスを受けること。

- 例: 人形の口から声が出ているように感じるが、本当は腹話術師の口から声が出ている。


# カクテルパーティー効果
多くの音の中から、自分が必要としている情報や重要な情報を無意識に選択することができる脳の働き

- 例: パーティーで大勢の人が雑談している中でも、友人の声を聞き取ることができる。


# ダブルフラッシュ効果（ダブルフラッシュ錯覚）
短いフラッシュが1回光る時に、短い音が2回提示されると、フラッシュも2回点滅したように感じられるという錯覚現象

聴覚の高い時間精度が視覚を補っているため起きる現象。


# マガーク効果
ある音韻の発話の映像と別の音韻の音声を組み合わせて視聴すると、第三の音韻が知覚されること。

- 例: 「ガ」と言っている映像に、「バ」と言っている音声を組み合わせて視聴すると、「ガ」でも「バ」でもなく、「ダ」と聞こえる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/eda81e1b-2213-3a53-d187-8a4b4ca390b3.png)
※引用: [PsychSeeing / 口は口ほどにモノを言う　～マガーク効果～](https://psychseeing.org/mcgurk_effect/)

# プルキンエ効果
暗くなると、短波長色が明るく見え、長波長色が暗く見える現象のこと。

- 例: 昼間は、同じ明るさに見えた赤と青の車が、夜になると赤の方が暗く見える。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/e06737a0-4494-ff1b-1866-1348f1088da6.png)
※引用: [COCOLOR / プルキンエ現象](https://www.cocolor.biz/colorlesson/%E3%83%97%E3%83%AB%E3%82%AD%E3%83%B3%E3%82%A8%E7%8F%BE%E8%B1%A1%E3%80%81%E3%83%97%E3%83%AB%E3%82%AD%E3%83%B3%E3%82%A8%E3%82%B7%E3%83%95%E3%83%88%E3%80%81%E8%96%84%E6%98%8E%E8%A6%96/)



# ドプラ効果（ドップラー効果）
波の発生源が移動する、あるいは観測者が移動することで観測される周波数が変化する現象のこと。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/df4d93d5-f51d-4cff-d1f0-99d7f77e01dd.png)
※引用: [Wikipedia / ドップラー効果](https://ja.wikipedia.org/wiki/%E3%83%89%E3%83%83%E3%83%97%E3%83%A9%E3%83%BC%E5%8A%B9%E6%9E%9C)



# 主題材料効果

問い（クイズ）の設定（ストーリー）を、よく慣れ親しんだ日常的な状況にすると、正答率が上がること。



# 典型性効果（プロトタイプ効果）

概念をカテゴリー分けする際に、典型事例との類似性によって特徴付けること。

- 例: ペンギンよりもスズメの方が `鳥` っぽく感じる。


# 最後に

本記事作成にあたり、以下を参考にさせていただきました！ありがとうございました！

- [VR技術者認定講習会・試験](https://vrsj.org/events/seminar/)
An unhandled fault has occurred in this flow An unhandled fault has occurred while processing the flow. Please contact your system administrator for more information.


このヘルプを読んでもよく分からん。

[Lookup field in flow throws error: 'An unhandled fault has occurred in this flow'](https://help.salesforce.com/s/articleView?id=000333444&type=1)

# 未解決
+ [Problem in Custom Metadata Types Basics module submodule Use Custom Metadata Types in Flows](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000HDqSt)


# 解決か？

必須フィールドに値がセットされていない。
+ [フローのエラー：このフローで未処理の障害が発生しました](https://salesforce.stackexchange.com/questions/329915/error-in-flow-an-unhandled-fault-has-occurred-in-this-flow)
+ [フローの処理中に未処理の障害が発生しました。詳細については、システム管理者に問い合わせてください。](https://www.reddit.com/r/salesforce/comments/puc985/an_unhandled_fault_has_occurred_while_processing/)


#  I used Custom Metadata Types (CMDT) to automate fields updates and populate some field values.  It works fine in the DEV1 org, but when I deployed the Flows and CMDT to DEV2, I am getting an 'UNKNOWN_EXCEPTION: An unexpected error occurred.  Please include this error Id if you contact support: 1864777442-209431 (1156755792)'. No other information.

+ [UNKNOW_EXCEPTION: An unexpected error occurred...](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000PfC9q)

:::note
I finally was able to isolate the issue.  For everyone's knowledge, I will explain.


There was an existing Subflow, that was triggered by Process Builder before.  We converted those Process Builders, in to a combined Record Triggered Flow, and the subflow was also included.  The subflow was set to run 'System Context with Share - Record Level Access Enforced' which unfortunately a Record Triggered flow cannot trigger!  I have changed the context to 'User or System Context - Depends on How the Flow is Triggered' and that resolved the issue.
:::
分散トレーシング(OpenTelemetry)を使う(その1)

分散トレーシングを普通のアプリで使うのも便利じゃないかなと思って、
色々書いてみようと思います。

## 分散トレーシング、OpenTracingとOpenTelemetryについて
分散トレースは、マイクロサービスのような分散ソフトウェアアーキテクチャのデバッグとモニタリングに便利なものです。
分散トレーシングで有名なのがOpenTracingで、色んな実装が乱立してきて良くないから、
仕様として統一しない？みたいなもんだと思います。
OpenCensusというのもあって、OpenTracingとOpenCensusをガッチャンコしたプロジェクトがOpenTelemetryとなってます。
なので、OpenTracingとOpenCensusは2019年に終了してます。

## OpenTracing APIとOpenTelemetry APIの互換
これからは、OpenTelemetry APIの時代みたいなんですが、
OpenTracing APIとの関係は↓に記載があります。
https://opentelemetry.io/docs/migration/opentracing/

## 分散トレーシングをざっくり

Trace: ざっくり言うと１リクエストと同等です。後述するSpanの集まりです。
Span: ひとつの境界内の処理。粒度としては、関数単位でもありますし、マイクロサービスのサービス単位でもあります。

Root Span: Traceの最初のSpanで、Trace全体の時間とほぼ同じです。下図のSpan Aが該当します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/353997/adc35498-5c3d-38a6-059a-953bc8af1e6b.png)

色々なユースケースがありますが、プロセスを跨るやつとかに使えそうです。
https://opentelemetry.io/registry/ を見てると、
たとえば、Apache →　Webアプリ、 Apache Camel → Apache Kafkaの流れで、
一気通貫でトレースが追えて性能ボトルネックを見つけれそうです。
　
## ざっくり動かす

### トレーサーのJaegerの起動
有名なトレーサーの一つで、Uberさんが開発されたそうでです。
参考：https://www.jaegertracing.io/

dockerでAll in Oneで入れるとすぐ動かせます。
参考：https://www.jaegertracing.io/docs/1.35/getting-started/

```sh
$ docker run -d --name jaeger \
  -e COLLECTOR_ZIPKIN_HOST_PORT=:9411 \
  -e COLLECTOR_OTLP_ENABLED=true \
  -p 6831:6831/udp \
  -p 6832:6832/udp \
  -p 5778:5778 \
  -p 16686:16686 \
  -p 4317:4317 \
  -p 4318:4318 \
  -p 14250:14250 \
  -p 14268:14268 \
  -p 14269:14269 \
  -p 9411:9411 \
  jaegertracing/all-in-one:1.35

```
http://localhost:16686/ でJaegerの画面が確認できます。

### サンプルのJavaアプリを動かす

gRPCのサンプルがあるので、それを動かしてみます。
https://opentelemetry.io/docs/instrumentation/java/getting-started/

```sh
$ git clone -b v1.47.0 --depth 1 https://github.com/grpc/grpc-java
$ cd grpc-java/examples
$ ./gradlew installDist
```

grpc-java/examplesに、[opentelemetry-javaagent.jar](https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar) をダウンロードして置いておきます。

#### サーバを起動

```sh
$ cd grpc-java/examples  # examplesで実行してください。opentelemetry-javaagent.jarもここに置いておく
$ export OTEL_TRACES_EXPORTER=jaeger
$ export JAVA_OPTS="-javaagent:./opentelemetry-javaagent.jar"
$ ./build/install/examples/bin/hello-world-server
```

#### クライアントを起動
```sh
$ cd grpc-java/examples 
$ ./build/install/examples/bin/hello-world-client
```

http://localhost:16686/ でJaegerの画面を見ます。

unknown_service:javaとかになってますが、出力されてます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/353997/66aeb982-2733-64a9-0e7c-ab7fb38b02cb.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/353997/691d7e45-6028-d0d7-fdbb-6bc3161362a8.png)

opentelemetryの出力を環境変数(OTEL_TRACES_EXPORTER)やシステムプロパティで簡単に切り替えらるので、便利ですね。

次は、Apache CamelやApache Kafkaなどで複数プロセス組合わたものでやってみようと思います。
Stripe Checkoutを使ってみた

## はじめに
以前関わっていたサービスでStripeを使っていたのですが触れる機会がなかったので簡単なサンプルを実装してみました。
今回はLaravelで実装しましたが特に理由はありません。

## サンプル動作イメージ
商品画面にStripe Checkoutの決済ボタンを設け、決済ボタンをクリックするとStripeの決済情報入力画面を表示して決済情報入力して決済、決済完了後同ページへリダイレクトするというシンプルなものです。

![stripe_checkout_demo.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2663462/fa4a47b4-f0ee-4171-985b-0d0c012c78ca.gif)

決済を行うとStripeのダッシュボードに決済履歴が表示されました。
![stripe_checkout_支払い.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2663462/e6f072e6-27ea-0f24-4cdc-8dd92da6ba8e.png)

## サンプルの実行
Dockerを利用できることが前提です。
また、Laravelの環境構築は割愛させていただきます。

### ソースコード
https://github.com/roytiger81102/docker-laravel/tree/stripe-demo

### Stripeアカウント作成, APIキー設定
Stripeのアカウントを作成し、公開可能キー,シークレットキーを`.env`に記載してください。

```.env
STRIPE_PUBLIC_KEY=
STRIPE_SECRET_KEY=
```

## おわりに
今回はStripeが提供している機能のうちCheckoutを試しました。
その他にもサブスクリプション（Subscriptions）など様々な決済機能が提供されています。
決済まわりはStripeを利用することで、サービスの中核の開発に注力できるのは改めて便利だと感じました。


## 参考
[Stripe API reference](https://stripe.com/docs/api/charges/create "Stripe API reference")
[Laravel8にStripeで決済機能をつけてみる【お試し編】](https://biz.addisteria.com/laravel-stripe/ "Laravel8にStripeで決済機能をつけてみる【お試し編】")
Experience Cloudサイトでのグローバル検索が正常に機能しない


元の質問: [Experience Cloudサイトでのグローバル検索が正常に機能しない件についてご教授ください。](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000JdSMV)


+ [How To Enable The Global Search in Salesforce Communities](https://advancedcommunities.com/how-to-enable-the-global-search-in-salesforce-communities/)
+ [Experience Cloud サイトの検索動作](https://help.salesforce.com/s/articleView?id=sf.networks_search_behavior.htm&type=5)
+ [グローバル検索でレコードが見つからない](https://help.salesforce.com/s/articleView?id=000330207&type=1)
技術習得は OR ではなく AND

![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1214128/1412a308-815c-6b6f-9db6-0b263bb63347.png)
# 技術習得は OR ではなく AND
リンゴとバナナどっち食べますか？元気よく「両方！！」って答えましょう。お腹空いていれば両方食べられますし、すいてなくても、少しずつ両方食べられますよね。技術も同じです。
## MacOSかWindowsか？
ビジネスワーカーで仕事で1台しか使わないのであれば、選択する必要ありますけれど、技術者だったら、片方しか知らないって残念ですよね。もっといえば、Linuxなんかもかじっておくべきです。他をしらないと各OSの特徴を理解できません。Windowsを使うからMacOSの利点欠点がみえますし、その逆もその通りです。
## AWSかGCPかAzureか
よく耳にする言葉です。
> AWSならわかる(できる)
自分で仕事狭めるならそれで通すのもありですけれどね。
# 同一技術を複数理解しているのは強み
最適解の選択には欠かせない知識です。
OptionSetValueから表示名を取得

//This method will return the label for the LCID of the account the IOrganizationService is using
public static string GetOptionSetValueLabel(string entityName, string fieldName, int optionSetValue, IOrganizationService service)
{
    var attReq = new RetrieveAttributeRequest();
    attReq.EntityLogicalName = entityName;
    attReq.LogicalName = fieldName;
    attReq.RetrieveAsIfPublished = true;

    var attResponse = (RetrieveAttributeResponse)service.Execute(attReq);
    var attMetadata = (EnumAttributeMetadata)attResponse.AttributeMetadata;

    return attMetadata.OptionSet.Options.Where(x => x.Value == optionSetValue).FirstOrDefault().Label.UserLocalizedLabel.Label;
}

//This method will return the label for the specified LCID
public static string GetOptionSetValueLabel(string entityName, string fieldName, int optionSetValue, int lcid, IOrganizationService service)
{
    var attReq = new RetrieveAttributeRequest();
    attReq.EntityLogicalName = entityName;
    attReq.LogicalName = fieldName;
    attReq.RetrieveAsIfPublished = true;

    var attResponse = (RetrieveAttributeResponse)service.Execute(attReq);
    var attMetadata = (EnumAttributeMetadata)attResponse.AttributeMetadata;

    return attMetadata.OptionSet.Options.Where(x => x.Value == optionSetValue).FirstOrDefault().Label.LocalizedLabels.Where(l => l.LanguageCode == lcid).FirstOrDefault().Label;
}
インフラのCI/CDはGitHub Actionsに任せた

2022.6.27からオンデマンド配信される [Cloud Operator Days Tokyo 2022](https://event.cloudopsdays.com/codt2022/talks/5) で、弊社ITスペシャリストリーダー平野美賢(@mihyon)により「インフラのCI/CDはGitHub Actionsに任せた。」というタイトルで発表が行われました。その発表資料をこちらにも共有します。

## はじめに
サービスのインフラ構築のCI/CDのツールとして色々試しましたが、GitHub Actionsで落ち着いたこの頃です。開発環境と本番環境で異なるパラメータの管理もGitHubで管理出来て楽々です。この資料では、GitHub Actionsを使ってインフラのCI/CDを実現する方法を初心者向けに紹介します。

## 目次
- GitHub Actions をCI/CDに導入するまで 
- GitHub Actions の採用 
- CI/CDへの道のり 
- 完成したCI/CD 
- 今後の課題 
- 公開資料


## インフラのCI/CDはGitHub Actionsに任せた

<script async class="speakerdeck-embed" data-id="da12aa2e735044d194f3124b7e420007" data-ratio="1.29411764705882" src="//speakerdeck.com/assets/embed.js"></script>
RetrieveAsIfPublished(true/false)

Cause:

RetrieveAsIfPublished = “True” means return the metadata(Entity, Attributes, Relationship, Optionset, option) including unpublished changes.

RetrieveAsIfPublished = “False” means return only the currently published Metadata, ignoring any unpublished changes.

In order to overcome with this issue, we set entity request “RetreiveAsIfPublished” property to false.

Solution:

So we used the revised code as below:

=====================================================================
//Retreive the entity request
                RetrieveEntityRequest attreq = new RetrieveEntityRequest();
                //retrieve all data for an entity
                attreq.EntityFilters = EntityFilters.All;
                //set the custom entity logical Name
                attreq.LogicalName = "new_employee";
                //Set RetrieveAsIfPublished value to false ignoring the unpublished changes
                attreq.RetrieveAsIfPublished = false;
                //Response the request RetreiveEntityRequest
                RetrieveEntityResponse attResponse = (RetrieveEntityResponse)_service.Execute(attreq);
【React】個人開発で使うために爆速でReactを勉強したい

# この記事の主題
元々大学時代に個人開発で、VueやNuxt.jsを使っていたんですけど、
社会人になってサーバーサイドの言語である「Java」をやり始めて、
「本業でJava、個人開発でサーバレスのモダンなやつで開発できたら、なんかめっちゃかっこよくね？」ってなったので、
最近のサーバレスの開発記事でよく目にする+モバイルアプリ開発のReactNativeにも拡張できる、
Reactを学習しようという運びになりました。

ただ、最初はwebアプリも作ってみたいと思ったため、Next.jsを学習するために、
なる早でReactを終わらせたかったのです。

# 留意事項
この学習のゴールを、「フレームワークを使う際に困らないようにする」というところに置いており、
複雑な概念はそこまで熱心にやっておりません。
また、基本的に遅延評価勉強法をベースとした学習をしています。

そのため、ある程度のことは、何かを作って調べながら身につけることを前提としているので、
知識の抜けもれはおそらく（きっと確実に）あります。

# かかった期間
おそらく2週間くらいで、稼働時間は一日あたり1h～4hくらい

# やったこと
### ①JavaScriptの復習
mapやアロー関数、promiseや、async awaitなど、
モダンJSのや自分の苦手分野に絞って学習をしました。
基礎の構文は研修中にJavaで書いて概念を理解していたので、
理解の滞っている部分に絞った学習をしました。

[非同期処理の完了を待つ方法！Promise＆async/await【分かりすぎて怖いJavaScript入門】](https://www.youtube.com/watch?v=Vhnz1V-v1cU)
[モダンフロントエンドエンジニアになるためのJavaScript入門 2022年版](https://www.udemy.com/share/105SzC/)

### ②Reactについて学習する(導入編)
Udemyの講座から、学習しました。
とにかく「Reactはなんぞや、どうやって勉強すんの」って疑問を解消してくれます。
わかり易すぎて度肝抜かれっぱなしでした。

ここでstateやuseStateはともかく、
useEffectによる依存関係などが難しかったので、そのレクチャーは何度も見返したり、コードを書きました。
あと、関数型コンポーネントを初めて使ってなんだかすごい感動しました。

[モダンJavaScriptの基礎から始める挫折しないためのReact入門](https://www.udemy.com/share/103Fxl/)

以下記事も勉強になりました。未だに振り返っています。
[React hooksを基礎から理解する (useState編)](https://qiita.com/seira/items/f063e262b1d57d7e78b4)

### ③公式docs
各宗教には聖典があるように、開発者には公式ドキュメントがあります。
どんなに急いで学習しても、一般的な標準を知るために、絶対に避けてはならないと思っています。
「tutorial」「Main Concepts」「Hooks」あたりは押さえておくのが吉です。
読んでてわからないところがあったらGoogle先生に投げてましたね。

[React公式ドキュメント](https://ja.reactjs.org/docs/getting-started.html)

### ④書籍から学ぶ
最後に、知識の抜けや漏れがないかを確かめるために、市販の参考書を買いました。
この書籍は個人的にはぼちぼちって感じでしたが、
サンプルで作るものが多かったり、Next.jsでの開発の橋渡しをしてくれるのでありがたかったです。

[React.js＆Next.js超入門 第2版](https://www.amazon.co.jp/gp/product/B08XBNGYVH/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&psc=1)

# Reactを書いてみて
Vue.jsを書いていた自分からすると、ぶっちゃけどっち使っても良いのかなとは思いました。
ただ、ルーティングやレンダリングに対してのコードが個人的に書きやすかったり、
踏み込んだ内容やエラー、更にはReactを用いたアプリの技術の検索をしても、かなりの量の記事が出てきて扱いやすいなとは思いました（これは主にNext.jsを書き始めて思ったことです）。

ただReactを普通に使う場合のCSSの選定には悩まされそうですね。スタンダードはJSX+tailwindcss(or Material-ui)とかなのでしょうか。
自分はNext.jsを使うことを前提にしていたので、CSS Modules+tailwindcssで学習していました。

[CSS Modules(Next.jsのdocs内のページに記載)](https://nextjs.org/docs/basic-features/built-in-css-support)

# 謝辞
読んでいただきありがとうございました！
少しでもReact学習のご助力になれれば幸いです。
【App Mesh】メッシュ内からIPv6対応の外部サイトにアクセスする時は「IP バージョンの設定」に注意する

[以前の記事](https://qiita.com/r-dohara/items/192b68f200002f2f546a)にて、メッシュ内からメッシュ外へ通信を行う方法として、アクセス先のエンドポイント専用の仮想ノードを作成するという方法を紹介しました。

ただその際、アクセス先のサイトがIPv6に対応しているかどうかで通信が失敗するという事例に遭遇したので、この記事ではそれについてまとめます。

## 結論
IPv6を用いる予定がないのであれば、
アクセス先のエンドポイント専用の仮想ノードを作成する際に、「IP バージョンの設定」をデフォルトとせず、IPv4が優先されるようにする。

## 失敗する原因
仮想ノードを作成する際、「IP バージョンの設定」という設定があります。
![ip_default.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2697194/ffcd319d-f3a0-69ce-bcc2-21fe352b323e.png)
ここを何も変更しなければ勿論この設定についてはデフォルトとなるのですが、
こちらデフォルトでは名前解決時にIPv4よりもIPv6を優先するような設定となっています。（[公式ドキュメント](https://docs.aws.amazon.com/app-mesh/latest/userguide/virtual_nodes.html#:~:text=IP%20version%20preference)）

ただ、特に意識せずにECSタスクを立ち上げた場合、ECSタスクはIPv6に対応していません。
（正確にはVPCのIPv6対応等が必要）

まとめると、名前解決はIPv6で行われるが、ECSタスクがIPv6に対応していないためエラーとなっていました。

## 対策
[結論](#結論)にも記載した通り、「IP バージョンの設定」をIPv4が優先されるものに変更したら解決します。
![ip_choices.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2697194/e3d6f011-20d3-9ce1-43e4-355e67e72c73.png)
画像でいうなら
- IPv4 を設定済み
- IPv4 のみ

の2つですね。

## 補足
ここまで書いてきた内容はアクセス先のサイトがIPv6に対応していなければ発生しません。
なので例えば「aws.amazon.com」へのアクセスは、「IP バージョンの設定」がデフォルト状態でも成功します。

**「aws.amazon.com」はIPv6未対応**
```
xxx>nslookup aws.amazon.com
サーバー:  xxx
Address:  xxx

権限のない回答:
名前:    dr49lng3n1n2s.cloudfront.net
Address:  18.65.165.68
Aliases:  aws.amazon.com
          tp.8e49140c2-frontier.amazon.com
```
※一部伏字

## まとめ
上記問題に遭遇した時は、curlコマンドを用いて接続確認をしていたのですが（[ECS Exec](https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/userguide/ecs-exec.html)を使用）、
エラー文が`curl: (35) error:1408F10B:SSL routines:ssl3_get_record:wrong version number`と、IPv6と直接結びつけるのが難しいものだったので苦戦しました。
（最終的にはAWSサポートのお力も借りました・・・）

なので、App Meshを使う際のちょっとした参考になればなと思います。

## 参考
- [Virtual nodes](https://docs.aws.amazon.com/app-mesh/latest/userguide/virtual_nodes.html)
- [デバッグ用にAmazon ECS Exec を使用](https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/userguide/ecs-exec.html)