OmniAICreator/Qiita-1.07M huggingface dataset:
Laravel　リレーション 1対多 多対多 とかまとめ

リレーション、わかっているつもりでも設計しようとする時によく混乱するのでまとめ。

https://readouble.com/laravel/8.x/ja/eloquent-relationships.html


### １対１

hasOne。（あまり使ったことない。）

Userが親モデル（主）。
Phoneが子モデル（従）。子モデルが `user_id` カラムを持つ。（親モデル名_id）。親モデルの「スネークケース」名に「_id」
親も子も名前は単数形。

```php:user.php
class User extends Model
{
    /**
     * ユーザーに関連している電話の取得
     */
    public function phone()
    {
        return $this->hasOne(Phone::class);
    }
}
```


```php:phone.php
class Phone extends Model
{
    /**
     * phonesテーブルにuser_idカラムが必要
     */
    public function user()
    {
        return $this->belongsTo(User::class);
    }
}
```
外部キーが`user_id` で無い場合は第２引数にカスタムキー名を渡す。

```php:phone.php
class Phone extends Model
{
public function user()
{
    return $this->belongsTo(User::class, 'foreign_key');
}
}
```
### １対多(One to Many)

hasMany。メソッドの名前を複数形にする必要あり。
親モデル hasMany 子モデル。もしくは Class 〇〇 hasMany 子モデルと考えると混乱しづらい。

```php:user.php
class User extends Model
{
    /**
     * 名前を複数形にする
     */
    public function phones()
    {
        return $this->hasMany(Phone::class);
    }
}
```

belongsToは1対1の場合と同じ。単数形のメソッド名。
```php:phone.php
class Phone extends Model
{
    /**
     * phonesテーブルにuser_idカラムが必要
     */
    public function user()
    {
        return $this->belongsTo(User::class);
    }
}
```

### 多対多(Many to Many)

中間テーブル(pivot table)が必要。メソッド名はお互いに複数形。belongsToMany。
テーブルは合計3つ必要。

中間テーブル作成。それぞれのテーブルの単数形(モデル名)をアルファベット順に並べる。
```
php artisan make:migration create_category_product_table --create=category_product
```

それぞれの中身。category_productがそれぞれのテーブルの_idを持つ。これでProduct、Categoryどちらからも呼び出せる。

```php:テーブル
products
    id - integer
    name - string

categories
    id - integer
    name - string

category_product
    category_id - integer
    product_id - integer
```

メソッド名はお互いに複数形。

```php:Product.php
class Product extends Model
{
    public function categories()
    {
        return $this->belongsToMany(Category::class);
    }
}
```

```php:Category.php
class Category extends Model
{
    public function products()
    {
        return $this->belongsToMany(Product::class);
    }
}
```
`attach`、`detach`、`sync` メソッドなどが使える。

https://readouble.com/laravel/8.x/ja/eloquent-relationships.html#:~:text=dissociate()%3B%0A%0A%24user%2D%3Esave()%3B-,%E5%A4%9A%E5%AF%BE%E5%A4%9A%E3%83%AA%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3,-%E9%96%A2%E9%80%A3%E4%BB%98%E3%81%91%EF%BC%8F%E9%96%A2%E9%80%A3

 Have a good relationship with relationships.
【Kotlin】各リストの要素を均等にマージする

各リストの要素を均等にマージする関数を実装した。

例えば [A, B] と [x, y, z] をマージすると
[x, A, y, B, z] となる。
```
    A   B
|||||||||||||
   x  y  z
```

実装：

```Kotlin
/**
 * 各リストの要素を均等にマージする。
 *
 * 例えば [A, B] と [x, y, z] をマージすると
 * [x, A, y, B, z] となる。
 * ```
 *     A   B
 * |||||||||||||
 *    x  y  z
 * ```
 */
fun <T> Iterable<List<T>>.mergeProportionally(): List<T> {
    return this
        .flatMap { list ->
            list.mapIndexed { index, element ->
                val position = (index + 1).toDouble() / (list.size + 1)
                position to element
            }
        }
        .sortedBy { (position, _) ->
            position
        }
        .map { (_, element) ->
            element
        }
}
```

使用例：

```Kotlin
fun main() {
    listOf(
        listOf("A", "B"),
        listOf("x", "y", "z"),
    ).mergeProportionally()
        .also { println(it) } // > [x, A, y, B, z]
}
```

説明と関数名をもうちょっといい感じにしたい。

／以上
Google UXデザイン：インタビューの準備

# はじめに

わたしが[Google UX Design Certificateで得られた素晴らしい体験][google]を、特に重要だと思われるポイントを小さく分割して、わかりやすく簡潔に紹介していきます。

興味があれば、ぜひ Google UX Design Certificateを受講してみてください。

[google]: https://qiita.com/mapami/items/7a0d0a3d4661c50f8bec

https://www.coursera.org/professional-certificates/google-ux-design

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/3729adea-8dba-b2a3-6127-9b0bf6886e54.png" width="800">

# インタビューのゴール

次の質問を自分に投げかけてみてください。

- ***<font color="MediumVioletRed">インタビューから何を学びたいのか？</font>***
- ***<font color="MediumVioletRed">共感すべきユーザーの問題やペインポイントはあるか？</font>***
- ***<font color="MediumVioletRed">インタビューしたいユーザーの特徴はあるか？</font>***
- ***<font color="MediumVioletRed">包括的でバランスの取れたデータを得るために、どれくらいの情報を持つべきですか？</font>***

ゴールを明確にすることで、理想的な参加者の特徴を見極めることができます。

ユーザーに共感する際の一般的なリサーチゴールの例をいくつか挙げてみましょう。
- 私の製品が解決しようとしている問題に関して、<font color="MediumBlue">人々が経験するプロセスや感情</font>を理解したい。
- 製品が解決しようとしているタスクに関して、<font color="MediumBlue">共通のユーザーの行動や経験</font>を特定したい。
- 私がデザインしている製品に関連して、<font color="MediumBlue">ユーザーのニーズや不満</font>を理解したい。

:::note info
天気予報のアプリをデザインする場合： 
***【予測できない天候に関連して、人々が経験する感情を理解すること】***

ショッピングアプリをデザインする場合：
***【カートに商品を入れたり出したりといった、オンラインショッピングに関わる一般的なユーザーの行動や体験を理解すること】***
:::

# 質問リストのベストプラクティス

インタビューのゴールを念頭に置きながら、インタビューの質問を書きます。

#### 自由形式の質問
参加者は自分の本当の考えや視点を共有することができます。

ただし、質問に参加者が望む回答に向けて誘導したり、プレッシャーをかけたりしないように留意してください。


#### 質問は短く、シンプルに
インタビュー参加者が質問内容を理解しやすいようにします。

#### フォローアップする
デザインプロセスの共感段階では、インタビューは会話形式であるべきで、参加者に詳しく説明するように促しましょう。参加者がインタビューの質問に答えた後、次のフレーズを使い、会話の流れを止めないように。
- <font color="MediumBlue"> 「なぜですか?」</font>
- <font color="MediumBlue">「それについてもっと教えてください」</font>


# 代表的なサンプル

インタビュー参加者候補に代表的なサンプルを作成することを目指します。代表サンプルとは、対象集団の特性を正確に反映しようとする部分集合のことです。

代表的なサンプルの参加者には、これまでの調査で代表者が少なかったユーザーグループを含める必要があります。

このような代表性の欠如は、多くの場合、年齢、人種、性別、能力による偏りの結果です。多様な参加者の中から選ぶことで、すべてのユーザーにとって素晴らしい体験を生み出すことができます。

# リクルート活動

***インタビュー参加者候補をどのように探せばよいのでしょうか？***

それは、勤務する会社、設計する製品の種類、プロジェクトの時間的制約、プロジェクトの予算、インタビュー対象者のアクセス性などに左右されることがあります。

#### 個人的に知っている人をリストアップ
現在または以前の同僚、上司、あるいはこのコースの仲間など、仕事上の知り合いに聞くこともできます。

#### SNSを利用
自分のソーシャルメディアのプロフィールからインタビュー相手を見つけることはすでに述べました。また、LinkedInのようなプロフェッショナルなネットワーキング・サイトを通じて、インタビュー対象者候補とつながることもできます。個人の興味に基づいたオンライングループも、素晴らしいリソースです。

#### 第三者機関のリサーチ・リクルート・エージェントを利用
エージェントは、時間の節約になるし、自分一人では到達できないような多様なユーザーにアプローチできることが多いので、便利です。この方法を利用するのは、このサービスを利用する予算があるプロジェクトに取り組んでいる場合のみと思われます。例えば、usertesting.comやuserinterviews.comなどの有料サービスがあります。

# サンプル

あなたは、フードデリバリーアプリをデザインするとした場合のサンプルを挙げます。

#### インタビューのゴール

- 多忙なスケジュールと食事計画を管理しようとする人々が直面する共通の課題を理解したい。
- レストランで注文する際に感じるフラストレーションについて理解したい。

#### 質問リスト

- あなたの現在のスケジュールと、仕事と食事計画のバランスを教えてください。
- レストランに食事を注文する頻度はどのくらいですか？ その際、どのような動機ですか？
- 注文のプロセスでどのような問題に直面しますか？ その際、どのように感じますか？
- これらの課題を解決する方法はありますか？

### 対象となる参加者の特徴

- 18歳〜62歳
- 大都市圏または郊外に居住している
- 週に1回以上、外食で料理を注文する人
- 異なる性別の参加者を含む
    - 障がい者を含む

# さいごに

素晴らしいインタビュー参加者を見つけるには、真の努力が必要ですが、素晴らしい調査を行うことで、その価値は十分にあります。
rbenvで3.1.2がインストールできない

# 環境
ubuntu: 20.04.5
rbenv 1.2.0: gitでインストール
ruby-build 20220930: gitでインストール

https://github.com/rbenv/rbenv

# 現象

```shell
$ rbenv install 3.1.2
...
current directory: /home/UserName/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/rbs-2.1.0/ext/rbs_extension
make DESTDIR\\=
make: error while loading shared libraries: libcrypt.so.1: cannot open shared object file: No such file or directory

make failed, exit code 127
...
        from ./tool/rbinstall.rb:899:in `block in install'
        from ./tool/rbinstall.rb:713:in `no_write'
        from ./tool/rbinstall.rb:899:in `install'
        from ./tool/rbinstall.rb:1068:in `block (2 levels) in <main>'
        from ./tool/rbinstall.rb:1043:in `foreach'
        from ./tool/rbinstall.rb:1043:in `block in <main>'
        from ./tool/rbinstall.rb:1127:in `block in <main>'
        from ./tool/rbinstall.rb:1124:in `each'
        from ./tool/rbinstall.rb:1124:in `<main>'
make: *** [uncommon.mk:383: do-install-all] Error 1
```
で止まってしまう現象が発生。libcrypt.so.1が見つからないようだ。

# 対策1
```shell
$ whereis libcrypt.so.1 

#見つからない場合
$ sudo dpkg --add-architecture i386
$ sudo apt update
$ sudo apt install libcrypt1:i386

$ whereis libcrypt.so.1                                                               
libcrypt.so.1: /usr/lib/x86_64-linux-gnu/libcrypt.so.1
```
libcrypt.so.1がインストールできた。

# 対策2
インストール出来てもこのファイルを使ってくれるかどうかは分からないので環境変数にPATHを通す。
```shell
$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/lib/x86_64-linux-gnu
$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/x86_64-linux-gnu 
```
この辺りは環境にもよるが手元の環境だと、上記の２箇所にlibcrypt.so.1があったので両方追加した。

# 解決
```shell
$ rbenv versions
3.1.2
```
行が削除されたコミットを特定するのにgit log -Sを使ってはいけない話（git log -Gを使うべき）

## 背景
仕事でコードレビューをしているときに「あれ、あの処理があったはずだけど消えてるな？どこで消えてるんだろ？」と疑問に思い、その処理の行が削除されたコミットを特定する方法を調べたら`git log -S "文字列"`で探すという情報を見つけましたが**それでは探せない例があるとわかった**ので備忘録です。

## git log -Sでは探せない例
例えば、`git log -S "function doSomething"`というふうに`doSomething`という名前の関数をコミット履歴から探そうとしたときに、1つのコミット内で`function doSomething`という文字列が同じ回数削除されていて同じ回数追加されていた場合に検知ができません。

`git diff`で説明をすると、`git diff`を実行して以下のような結果になるときには実際に`function doSomething`が削除されているにもかかわらず`git log -S "function doSomething"`では検知ができません。

```
$ git diff <hash>
...
-    function doSomething(int a) {
...
+    function doSomethingElse(int b) {
```

### 理由
それが仕様だからです。
[ドキュメント](https://git-scm.com/docs/git-log#Documentation/git-log.txt--Gltregexgt)を見ると以下のように書いてあります。

> To illustrate the difference between -S<regex> --pickaxe-regex and -G<regex>, consider a commit with the following diff in the same file:
> 
> ```
> +    return frotz(nitfol, two->ptr, 1, 0);
> ...
> -    hit = frotz(nitfol, mf2.ptr, 1, 0);
> ```
> While git log -G"frotz\(nitfol" will show this commit, git log -S"frotz\(nitfol" --pickaxe-regex will not (because the number of occurrences of > that string did not change).

## 結論
行が削除されたコミットを特定するのには`git log -G`を使うと漏れがないと思います。

ただ、`git log -G`ではファイル内で処理を移動するようなリファクタリングのコミットも検知されてしまいます。そのようなリファクタリングの差分を無視したいという場合には`git log -S`が使えるかもしれません。
Turbo で AdminLTE を使う場合の対応

# Turbo を使いたい！

[Turbo] を使うと画面遷移が高速になり、ユーザビリティが向上します！
が、まだ Turbo に対応しているものは少ないようです。
今回、[AdminLTE] (3.1.0) を使っている時に動かない部分があったので、その対処方法を書き留めます。

# Turbo で AdminLTE の困りごと

Turbo で何が困るのかというと、画面遷移時に JavaScript が読み込まれない事です。
色々読み込まないから高速！なのですが、JavaScript が読み込み時に処理が走る前提のものもあるので、それらについては対処が必要です。
そして、AdminLTE にも JavaScript 読み込み時に実行する処理がいくつかあります。

まずは、`Layout Plugin` でサイドバーやログインフォームの高さを修正する処理です
(このせいで、サイドバーがスクロールできなくなりました)。

https://adminlte.io/docs/3.2/javascript/layout.html

他には、`Push Menu Plugin` (サイドバーを最小化できるやつ) で `data-enable-remember="true"` とした場合、記憶したサイドバーの状態を復元する処理もあります
(他にもありそうだが、対処方法は一緒なはず)。

https://adminlte.io/docs/3.2/javascript/push-menu.html

# 対処方法

対処としては、`"turbo:load"` イベントで、必要な処理を呼び出します。

```application.js
const apply_at_turbo_load = () => {
  $("body").Layout("fixLayoutHeight");
  $("body").Layout("fixLoginRegisterHeight");
  $('[data-widget="pushmenu"]').PushMenu();
};

document.addEventListener("turbo:load", apply_at_turbo_load);
```

# ついでに

Turbo では、訪問したページをキャッシュしておき、同じページを開くとき、読み込む前にキャッシュを表示する `preview` 機能があります。
が、そのせいで、前に表示されたフラッシュメッセージや、閉じたはずのサイドバーが一瞬見えてしまいます。
以下を記載して `preview` しないようにした方が良いかも。

```application.html
    <meta name="turbo-cache-control" content="no-preview">
```

# 参考

- https://turbo.hotwired.dev/handbook/building#observing-navigation-events
- https://turbo.hotwired.dev/handbook/building

[Turbo]: https://turbo.hotwired.dev/
[AdminLTE]: https://adminlte.io/
連想配列の中に一つでも指定した値が存在するか確認する方法

はじめに
--
reactでコードを書いていると、配列を使った実装が多いなぁと感じます。(reactだけじゃないかもしれませんが）
今回は、配列の中に指定した値が存在しているかチェックする必要があったため調べて実装したことを備忘録として残そうと思います。

前提
--
自分のコードをそのままコピペすると前提説明が長くなりそうなので簡単な例を作りました。

例として、下記のような果物の連想配列があるとします。
ゴールはfruitsのnameの値に"apple"があれば、trueを返すコードを実装することです。
~~~react
const fruits = [{name: "apple", price: 200,}, {name: "lemon", price: 100,}, {name: "orange", price: 300}]
~~~


someメソッドを使用する
--
下記のsomeメソッドを使用すれば簡単にコードを書くことができます。
someメソッドは、指定された関数のなかで一つでもtrueを返した場合はtrueを返し、それ以外はfalseを返します。

~~~react
array.some(arr => ~ )
//他にも引数を指定できますが、今回は割愛します
~~~

実際のコード
--
someメソッドを使用して下記のように記述をすれば、fruitsのnameの値に"apple"あればtrueを返してくれます。
もちろん配列に値が存在しない場合はfalseを返してくれます。

~~~react
const fruits = [{name: "apple", price: 200,}, {name: "lemon", price: 100,}, {name: "orange", price: 300}]

const checkFruits1 = fruits.some(fruit => fruit.name === "apple")
console.log(checkFruits1)
//=> true

const checkFruits2 = fruits.some(fruit => fruit.name === "banana")
console.log(checkFruits2)
//=> false
~~~

終わりに
--
配列の存在チェックに使えるメソッドは他にも"indexOf"や"includes"メソッドなどがあります。
色々な場面に即した実装ができるようになるために、またの機会に他のメソッドもまとめて理解を深めようと思います。

参考
--

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/some
Dockerコマンドを実行時にエラー発生 "Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running"

Docker学習していたらエラーが出たので解決策の共有、忘備録として記事を出します。

## 1.エラー
docker psコマンドを実行したらエラー発生。
````
$ docker ps
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running
````

## 2.原因
ただ単にDockerが起動していないだけでした。
そのため、下記(3.解決)を実行してDockerを起動させれば解決するはずです。

## 3.解決
以下のコマンドを実行してDockerを起動させてください。
````
$ sudo service docker start
````
これでうまくいくはずです。
````
$ docker ps
CONTAINER ID   IMAGE                  COMMAND                  CREATED      STATUS      PORTS                    NAMES
````
うまくいきました！

::::note warn
WSL2(ubuntu)環境だと上記のコマンドを実行してもDockerが起動しない場合があります。
その際は、以下の方法を参考にしてください。
::::
https://qiita.com/Muusann/items/73db73fca74ee616fff6

Docker使う時にいちいち起動するのは面倒くさい…ので.bashrcに記載することに。
それと、実行権限の割当も追加しておくことに。

````.bashrc
# 一番下に記載
sudo chown $(whoami) ///var/run/docker.sock
sudo docker service start
````
これでターミナルを立ち上げるときも自動で実行されるはずです。
 

## 4.最後に
Dockerコマンドについてのエラーは、Dockerが起動してなかったり、権限がなかったりする場合が多いのでエラーに遭遇したら参考にしてみてください。
PowerAutomate: Webスクレイピングした結果を、Power BI ストリーミングデータセットに格納して日々閲覧

# 背景
初夏、会社であることを依頼された「外部サイトに公開されている Excel の価格を見える化出来ないか？」
とりあえず、Power BI で外部サイトの Excel から必要な部分のみ抽出することをしていたら・・

最近になって、過去価格一覧は有償化された

とはいえ、最新価格はそのまま問題なく提供されていたので、これをストリーミングデータセットに格納して閲覧できるようにした記録

# 概要
1. Web スクレイピング
1. 取得した結果を、Power BI ストリーミングデータセットにプッシュ
1. ストリーミングデータセットのレポートを生成
1. 受信購読設定

# 詳細
## Web スクレイピング
スクレイピングは以下

https://qiita.com/baku2san/items/0b42de6e69d3c0eef100

## 取得した結果を、Power BI ストリーミングデータセットにプッシュ
1. まずはデータセットを準備ってことで、新規作成<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/0305f6f6-5fca-9165-e6d3-ca5125741ae6.png)<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/68d0e6a9-a616-7706-a57a-58b6b3a7b299.png)
1. データセットに名前を付けて、必要な項目を設定して、履歴をON<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/da7dd852-1e99-2be5-ace9-684f15057a94.png)
1. あとは、スクレイピングした価格を、Power Automateで突っ込むだけ<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/0acf1e2e-1db6-5a3a-ec76-0588d836ab2a.png)


## ストリーミングデータセットのレポートを生成
1. データセットから「レポートの作成」を選択<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/6ca1e27e-e5df-2d7e-5e43-289954067e47.png)
1. あとは、適当にレポート作成<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/101a43e3-731f-e9c1-c9da-ac386ed94bd3.png)

::: note info
- メジャーは作れない？
- テーブルは単一？
- Q&A を貼り付けておくと、"Latest 価格" みたいな感じでメジャー的なことは出来る
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/8da2a379-b8a5-9f1c-2aec-814d04e729b4.png)

:::


## 受信購読設定
あとは、普通に受信購読をするだけ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/b55c62cb-8384-fbcc-6eb3-4c19c8abedbb.png)

# あとがき
こういったレポートを複数統合する方法はあるんだろうか？
【Version確認】各ミドルウェアのVersion確認まとめ

## _Version確認まとめ_
アプリ作成時に、自分の環境のバージョン把握は必須となるため、各ミドルウェアのVersion確認方法を自分なりにまとめてみた…

## VersionUpのメリットデメリット
- __メリット__
1. Webサイトの安全性が向上する
セキュリティ上の問題や不具合へのサポートがあるため、サイト攻撃の可能性が低くなります。

2. 最新の環境での開発が可能になる
新しい機能やプラグインが利用可能になることで、今まで実現が難しかったことが簡単にできるようになり、開発内容の広がりが期待できます。

- __デメリット__
1. サイトが正しく表示されなくなる
過去に構築したサイトについて、最新のプラグインやテーマが非対応の場合があります。
その場合、Webサイトの一部が正しく表示されなかったり、最悪の場合はサイト全体が動かなくなったりする可能性があります。

2. 廃止された関数の改修が発生する
バージョンアップに伴い、今まで使えていた関数が廃止され、別の関数への置き換えを求められる場合があります。
サイトを今まで通りに表示させるためには、過去に構築したプログラムの関数を一つ一つ置き換得る作業を行わねばならず、多くの労力を使うこととなります。

## Version確認コマンドまとめ
### RailsVersion確認
~~~:Console
username:~/environment $ rails -v
(出力)Rails 6.1.4
~~~

### NodeVersion確認
[参照：Node.js](https://www.nnn.ed.nico/contents/guides/97/content)
~~~:Console
username:~/environment $  node -v
(出力)v16.13.1
~~~

### YarnVersion確認
[参照：yarn](https://tcd-theme.com/2021/10/javascript-yarn.html)
~~~:Console
username:~/environment $ yarn -v
(出力)1.22.11
~~~

### convertVersion確認
[参照：convert](https://imagemagick.org/script/license.php)
~~~:Console
username:~/environment $ convert -version
(出力)Version: ImageMagick 7.1.0-6 Q16-HDRI x86_64 2021-08-22 https://imagemagick.org
(出力)Copyright: (C) 1999-2021 ImageMagick Studio LLC
(出力)License: https://imagemagick.org/script/license.php
(出力)Features: Cipher DPC HDRI OpenMP(4.5) 
(出力)Delegates (built-in): jng jpeg png tiff zlib
~~~

### Sqlite3Version確認
irbとは、Rubyをターミナル上で実行するためのコマンド
~~~:Console
username:~/environment $ irb
3.1.2 :001 > require 'sqlite3'
(出力) => true 
3.1.2 :002 > SQLite3::SQLITE_VERSION
(出力) => "3.36.0" 
3.1.2 :003 > exit
~~~

## まとめ
開発する際に、Versionを決めていないと環境によって様々なエラーが発生してしまうため、事前に決める必要がある！！
また、調べる際も自分のバージョンに合ったものを調べる必要があることが知れた💡
デザインパターン_TemplateMethod

## 参照
[wiki-Template_Method_パターン](https://ja.wikipedia.org/wiki/Template_Method_%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3)

## TemplateMethodパターンとは
TemplateMethodとはGoFによって定義されたデザインパターンの1つであり，「振る舞い」に属している.
おおまかなアルゴリズムをあらかじめ決めておいて，そのアルゴリズムの具体的な設計を，派生クラスに任せる事である．
そのため，システムのフレームワークを構築するための手段としてよく活用される.

[wiki-Template_Method_パターン](https://ja.wikipedia.org/wiki/Template_Method_%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3)より引用
## クラス図
![450px-Template_Method_UML_class_diagram.svg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2736795/ba3d78f1-1d7c-0610-9926-2cd2a4eefcd7.png)
[wiki-Template_Method_パターン](https://ja.wikipedia.org/wiki/Template_Method_%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3)より引用

## 各機能

### Abstract
- Method1,Method2は純粋仮想関数で定義し，具大的な設計は派生クラスに任せる

- TemplateMethodは基本的にはMethod1,Method2を使った処理を纏める時に使用する事が多い.

### Concrete
- 基底クラスであるAbstractから引き継いだ純粋仮想関数の設計などをするクラス．

## 処理

### Abstract
```C++:Abstract.cpp
#pragma once

template <class T>
class Abstract
{
private:
    T obj;
public:
    void TemplateMethod() 
    {
            obj.Method1();
            obj.Method2();
    };
};
```


### Concrete
```C++:Concrete.cpp
#pragma once
#include<iostream>
#include "Abstract.h"

using namespace std;

class Concrete1 
{

public:
    Concrete1() {};
    ~Concrete1(){}

    void Method1() { cout << "concrete1:Method1" << endl;; }
    void Method2() { cout << "concrete1:Method2" << endl;; }
};

class Concrete2 
{
public:
    Concrete2() {};
    ~Concrete2() {}

    void Method1() { cout << "concrete2:Method1" << endl;; }
    void Method2() { cout << "concrete2:Method2" << endl;; }
};
```


### main
```C++:main.cpp
#include<iostream>
#include "Concrete.h"

using namespace std;

int main()
{
    Abstract<Concrete1> concreate1 ;
    Abstract<Concrete2> concreate2 ;

    concreate1.TemplateMethod();
    concreate2.TemplateMethod();
    
    return 0;
}
```
PhpStormの便利機能

## 概要
最近未経験からエンジニアに転職したひよっこエンジニアです。
スキルアップのために、不定期で30分でインプットしたことをまとめて投稿していきます。
第一弾として本記事では、職場で使っている**PhpStormの便利機能・ショートカットキー**についてやっていこうと思います。

## PhpStorm便利機能3選
### 1. 検索系
#### 1-1. どこでも検索：「shift+shift」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680888/aafb7292-46e2-c59b-2e43-4de90eabe103.png)
※**ファイル名検索：「⌘+shift+o」**、**クラス名検索：「⌘+o」** もあるみたい。

#### 1-2. 複数ファイル内検索：「⌘+shift+f」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680888/68cf0e51-a9d0-3004-08d3-e4fa2ff65dc0.png)
※「⌘+shift+r」：複数ファイル内置換も可能。
　
### 2. ファイル移動：「⌘+↑」→「⌘+↓」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680888/6dccb1c4-d422-f4f1-bc2b-f9c17ab4bf3c.png)
「⌘+↑」：画面上部の階層が表示されているバーへ移動し、方向キーで階層や階層内のファイル選択。
「⌘+↓」：選択ファイルを開く。
　
### 3. ローカル内DBのER図出力
新しいプロジェクトにjoinした際に、ローカル内にあるDB全体図の把握に使えそう。
### 手順
1. 画面右上の「データベース」タブから該当DBを選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680888/01909ae2-1693-ca9e-62c5-e40c4a6665ae.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680888/cd60ed19-b9b3-a000-2f48-d7c0b9294bbe.png)
2. データソースを入力。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680888/93dc268c-ea0b-cf84-f531-6596b0fd8cd5.png)
3. 読み込んだDBをER図におこす
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680888/440a9458-d212-0132-5c63-c610db75a510.png)
4. 開いたダイアグラムを画像として保存する。

## おまけ
3選のつもりが調べていると使ってみたい機能があったので、おまけとして載せておきます。
### プロパティのgetter/setter作成：「⌘+n」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680888/880ae3b1-6744-a8fb-b822-bcab7f3b28b6.png)
- 該当プロパティを選択し、「⌘+n」を押すとgetter、setter、getter/setterが選択でき作成可能。

他にも[ショートカットキー](https://pleiades.io/sites/willbrains.jp/keymap/pdf/shortcut_phpstorm_mac.pdf)や[便利機能](https://www.karakaram.com/phpstorm-useful-tips2/#generate)があるようなので、日々触って使いこなしていこうと思います。

短時間でのインプット/アウトプットが目的なので文章が雑でクオリティが低いと思いますが、これから書き溜めていこうと思います。
AWS lightsail 静的ip固定 STATIC IP ADDRESSES

参考
https://lightsail.aws.amazon.com/ls/docs/ja_jp/articles/lightsail-create-static-ip


まずはlightsail管理画面へ
https://lightsail.aws.amazon.com/ls/webapp/home/instances


networking > create static ip と選択

Attach to an instance で
先程作ったサーバーを選択
そしたらピンアイコンが付きましたね。
nodeのアップデート

https://phoenixnap.com/kb/update-node-js-version#:~:text=Update%20Node%20JS%20on%20Windows%201%20Navigate%20to,checking%20the%20box%20and%20click%20Next.%20See%20More.


npm ERR! Error: EACCES: permission denied, access '/usr/local/lib'

上記のようなエラーが出た。
sudo を付けて

sudo npm install -g n

上記のようなコマンドにすることで解決した。
FlutterでiOS extensionにdart-defines flavorを伝える

## 問題
flavorでdev, stg, prod環境を分ける。[リンク](https://zenn.dev/riscait/articles/separating-environments-in-flutter#flavor%E3%81%AB%E5%AF%BE%E5%BF%9C%E3%81%99%E3%82%8B-xcconfig-%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E4%BD%9C%E6%88%90)に従っって設定したが、extensionを使用ているため、
何も設定しないで、--releaseでbuildすると、以下のエラーで失敗する。
```
error: Embedded binary's bundle identifier is not prefixed with the parent app's bundle identifier.

            Embedded Binary Bundle Identifier:      com.room8.app.BroadcastExtension
            Parent App Bundle Identifier:           com.room8.app.stg
```

## 解決
1. extensionの配下にxcconfigファイルを置く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2332865/cf4bae45-5b31-54b7-43f0-906fdea0fc27.png)

2. Runnerのinfo設定でxcconfigファイルを選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2332865/03f250f1-6557-213a-469c-cec22de0b9ab.png)


参考：[stack overflow](https://stackoverflow.com/questions/69808448/setting-ios-today-extension-bundle-version-to-flutter-flutter-build-number/69898579#69898579)
AMDGPU で Failed to initialize parser -125 エラーのメモ

一般的に Desktop 利用(Mesa とか OpenGL アプリ実行とか)生じるエラーのようですが, ROCm で計算させていても生じました.
現状解決策はありません.

https://bugzilla.kernel.org/show_bug.cgi?id=205089

ハングすることもあるようですし, ハングしないときもあるようです.
著者の場合は ROCm Whisper 動かしていて発生しました.
このときはプロセス temrinate できました(システムハングにはならず, 再度 ROCm アプリ実行できた). 

ハングせずに動くのであればそのまま使ってもよさそうですが... 必要に応じてリセットかけて対応しましょう :cry:
MacBookAirの蓋を閉じて開けるとCAPS LOCKが勝手にオンになる

# 問題

MacBookAirの蓋を閉じて開けるとCAPS LOCKが勝手にオンになる。
キーボードの修飾キーの設定でで CAPS LOCK は COMMAND に置き換えているのに何故かこの現象が起こる。


# 原因

- MacBookの蓋を閉じてしばらくするとスリープ的な状態になる
- スリープ状態でMacBookの蓋を開くと数秒程度だけCAPS LOCKキーが有効になる

というものだった。
このタイミングで蓋を開けた時に手がCAPS LOCKキーに触れてしまっていたせいで CAPS LOCKがオンになっていたらしい。

キーボード設定の修飾キーが反映されないタイミングがあるんだろうか。

# 端末

- MacBookAir 2020

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# Twitter

https://twitter.com/YumaInaura
EC2インスタンスのインスタンス停止→インスタンスタイプ変更→インスタンス開始をCloudShellで実行してみた。

# はじめに
こんにちは、山田です。
今回は、EC2インスタンスのインスタンス停止→インスタンスタイプ変更→インスタンス開始をコマンドで実行してみました。

# 概要
今回は、CloudShellからコマンドにて、インスタンス停止・インスタンスタイプ変更・インスタンス開始を実施していきます。
![WS000024.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1096361/a4c64980-24b7-ad57-1873-56676f49baa5.jpeg)

# 
今回は、``m1.medium``から``t2.micro``にインスタンスタイプを変更していきます。
![WS000026.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1096361/c9efd42f-570d-c749-4bcf-e0d35209d77a.jpeg)

下記が実行するコマンドです。
```sh
aws ec2 describe-instances --query 'Reservations[*].Instances[*].[State.Name, InstanceId]' --output text |
> grep running |
> awk '{print $2}' |
> while read line;
> do aws ec2 stop-instances --instance-ids $line;
> sleep 1m;aws ec2 modify-instance-attribute --instance-id $line --instance-type '{"Value": "t2.micro"}';
> aws ec2 start-instances --instance-ids  $line
> done
```
①インスタンスの状態が``running``のインスタンスIDを取得する。
```sh
aws ec2 describe-instances --query 'Reservations[*].Instances[*].[State.Name, InstanceId]' --output text | grep running | awk '{print $2}' ｜
```
②``while文``にてインスタンス停止、インスタンスタイプ変更、インスタンス開始の繰り返し処理を実行する。
```sh
while read line;
> do aws ec2 stop-instances --instance-ids $line;
> sleep 3m;aws ec2 modify-instance-attribute --instance-id $line --instance-type '{"Value": "t2.micro"}';
> aws ec2 start-instances --instance-ids  $line
> done
```

# 動作確認
CloudShellにてコマンドを実行します。
![WS000027.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1096361/1cec6d39-0aaa-fae8-ff7e-e0244544b419.jpeg)

インスタンスタイプが``t2.micro``になっていれば完了です。
![WS000028.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1096361/fa7b4a02-5db2-664f-fa1a-452f8f9faca4.jpeg)
Amazon SQS デッドレターキュー とは

## 勉強前イメージ

何らかの理由で届かなかったキューのこと指す？

## 調査

### まず Amazon SQS とは

フルマネージドのキューイングサービスで
ソフトウェア間を直接データを渡すのではなく、第三者経由でデータを渡すことで、送信側と受信側が好きなときに処理を行うことができます。
そのキューイングができるサービスがSQSになります。

### デッドレターキュー とは

デッドレターキュー(Dead Letter Queue)、略して DLQ と書きます。
DLQは正常に処理できないメッセージがキュー内に残り続けないように、移動させる機能になります。
また、DLQに入ったキューは一時的な障害等でない限りずっと残り続けます。
DLQはそもそも処理できないということを通知したり、処理が成功しない理由を調べるために役立ちます。

言葉は [こちらの前提知識](https://qiita.com/miyuki_samitani/items/e46ef9452fcd73f9d240#%E5%89%8D%E6%8F%90%E7%9F%A5%E8%AD%98) に記載していますが
SQSはコンシューマ(メッセージをポーリングするアプリケーション)が
指定された回数分メッセージの処理に失敗するとDLQに入ります。
なので、DLQに入るタイミングも指定することが出来ます。

以下がマネジメントコンソール上での設定画面になります。
オプションなのでデフォルトでは無効ですが有効にすると設定画面が出てきます。
またDLQ用のARNを指定することでそちらにキューが飛んでcloudwatchアラームと組み合わせることでDLQの通知を行うことも出来ます。

![1Amazon SQS - Google Chrome 2022-10-04 19.14.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/427b0936-aeca-aa9d-c379-96c5fdd99e3e.png)

## 勉強後イメージ

「これもう処理出来ないよ」って箱に入れるイメージかな？
確かにタイムアウトみたいなの設けてたらキュー処理出来ないのもわかるし、原因もわかるね。

## 参考

- [AWS CLIでAmazon SQSのデッドレターキューを設定してみた](https://zenn.dev/amarelo_n24/articles/e20da70629c77e)
- [SQSデッドレターキューにメッセージが入ったことを検知するメトリクスはどれが良いのか](https://dev.classmethod.jp/articles/sqs-dead-letter-queue-metrics-for-alert/)
aws cdk v2 でクラスターモードオフなelasticacheを作成

# 環境

```bash
cdk --version
2.44.0 (build bf32cb1)
```

# 結論
aws cdk でelasticacheを作成するときに

- クラスターモード オフ
- マルチAZ オン

を満たす一例は下記です。

```cdk.ts
    const subnetGroup = new CfnSubnetGroup(this, 'redis-cluster-subnet-group', {
      cacheSubnetGroupName: 'redis-private-subnet',
      subnetIds: vpc.privateSubnets.map(({ subnetId }) => subnetId),
      description: 'private subnet',
    });

    const redis = new CfnReplicationGroup(this, 'redis-cluster', {
      engine: 'Redis',
      cacheNodeType: 'cache.t4g.micro',
      engineVersion: '6.2',
      replicasPerNodeGroup: 1,
      numNodeGroups: 1,
      replicationGroupDescription: 'cdk setup',
      cacheSubnetGroupName: subnetGroup.cacheSubnetGroupName,
      multiAzEnabled: true,
    });

    redis.addDependsOn(subnetGroup);
```

`numNodeGroups`が2以上になると、クラスターモードが`オン`になり、`プライマリエンドポイント`・`リーダーエンドポイント`が発行されませんでした。

上記のデプロイ後、管理画面でみるとこうなります↓
すでに削除して、リソースはないのですが、念の為、ARNとか黒塗りにしてます。

![スクリーンショット 2022-10-04 18.57.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183059/e8e99bf4-0fff-adcc-3387-da0ab032a047.png)|
|:-:|

elasticacheのcdkってちょっちわかりにくいですよね。。。
ServerlessFrameworkでLambdaをVPCの中にいれようとしたらEC2の権限エラーがでる

# はじめに

ServerlessFrameworkで作成したLambdaにRDS通信を設定する作業を行っていたときに、VPC設定でつまづいたのでまとめます
設定の参考になる記事はあったのですが、説明が不足していたようだったので解決方法をまとめます

# 問題

ServerlessFrameworkでVPCの設定を行います
そこで以下の記事を参考に、IAMにEC2の権限を付与しました

```yml:serverless.yml
  iamRoleStatements:
    - Effect: "Allow"
      Action:
        - "ec2:CreateNetworkInterface"
        - "ec2:DescribeNetworkInterfaces"
        - "ec2:DeleteNetworkInterface"
      Resource:
        - "*"
```

しかし、実行コマンドを叩くと以下のエラーが発生します

```
ApiLambdaFunction (AWS::Lambda::Function) Resource handler returned message: "Your access has been denied by EC2, please make sure your request credentials have permission to DescribeSecurityGroups
```

# 解決方法

コマンドを実行するユーザーにも権限を付与する必要がありました
以下のコマンドの場合、アクセスキーを持っているユーザーのポリシーにもEC2の権限を追加しました

```
docker-compose -f docker-compose.production.yml run --env AWS_ACCESS_KEY_ID=XXXXXXXX --env AWS_SECRET_ACCESS_KEY=XXXXXXX --rm app make deploy
```

```
# 以下の権限をsls実行ユーザーに追加
ec2:CreateNetworkInterface
ec2:DescribeNetworkInterfaces
ec2:DeleteNetworkInterface
```

# おわりに

よく読むと解決できるのですが、さらっと読んでいる感じではserverless.ymlの修正だけでいけそうにみえました
少し時間はかかりましたが無事VPCの中に入れられました

# 参考

https://qiita.com/70_10/items/ae22a7a9bca62c273495
Netlify のビルドイメージを Xenial から Focal へ移行した

# Netlify のビルドイメージを Xenial から Focal へ移行した

ある日、Netlify UI の `Build image selection` に以下の警告が出るようになりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/0f1c8bf2-642a-b1c7-f412-312d491c4126.png)

> After November 15, 20022, the Xenial build image will not be supported. To avoid build failure, select another build image.

2022 年 11 月 15 日以降、Xenial ビルドイメージを使用したビルドはすべて失敗するようになるみたいです！
新しいビルドイメージ Focal に移行する必要があります。

# Xenial ってなに？

Xenial や Focal というのは、 Ubuntu のバージョンです。

| バージョン | コードネーム | 読み方     |
| ---------- | ------------ | ---------- |
| 16.04 LTF  | Xenial       | ジニアル   |
| 20.04 LTS  | Focal        | フォウカル |

# Focal イメージを試す方法

本番環境を汚さずに、事前に Focal で動作確認がしたかったので、方法を調べました。
Netlify 公式の移行ガイドがとても丁寧だったので、ほぼそのまま手順を日本語で記載します！

1. まず、Netlify UI の `Deploys` ページから、現在公開されているデプロイ（通常、最新の本番用デプロイ）を選択します。
1. デプロイのログページの上部で、`Lock publishing to this deploy` ボタンをクリックします。デプロイがロックされると、公開済みサイトを変更せずに新しいデプロイを実行できます。
   ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/91ba590e-0118-487e-70ee-07dcb2e19754.png)
1. `Deploy settings` ボタンをクリックし、 `Build image selection` までスクロールし、 `Focal` ビルドイメージを選択します。
   ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221845/48037cb4-c936-8998-d771-adbceee70037.png)
1. `Deploy` ページに戻り、 `Trigger deploy` ボタンをクリックします。
1. 新しいデプロイのビルドが開始されます。成功したら、 `Preview deploy` をクリックして、そのバージョンのサイトを表示します。サイトが正常に動作している場合は、設定完了です！ `Deploy` ページに戻り、 `Unlock to start auto publishing` をクリックして、ビルドを正常に実行し続け、新しいビルドイメージを使用できるようにします。
1. デプロイに失敗したり、サイトが正常に動作しない場合は、トラブルシューティングを行う必要があります。トラブルシューティングを行う時間がない場合は、Xenial イメージに切り戻して、再度 `Unlock to start auto publishing` を実行します。

# さいごに

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

- [Please read! End of support for Xenial build image: Everything you need to know](https://answers.netlify.com/t/please-read-end-of-support-for-xenial-build-image-everything-you-need-to-know/68239)
- [Netlify でビルド用イメージとして使用していた Ubuntu Xenial のサポートが切れるため Focal にアップグレードする](https://blog.symdon.info/posts/1663980435/)
WindowsからMFA + aws cli + Session Managerを駆使してSSH接続(or ポートフォワード)

# はじめに

バッチファイル内でコマンドの実行結果を複数の変数に取りだし利用する - Qiita
https://qiita.com/SECUAL_masa/items/a9a17e78e935ddb1be47

上記の記事の最後でも書いたが、実際にやりたかったことを記事にして公開する。

# やりたかったこと

WindowsからAWSのSession Managerを利用して目的のインスタンスにSSH接続。

# 注意事項

Windowsでaws cliを環境変数(AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY/AWS_DEFAULT_REGION)を駆使して利用されている場合は既存の設定がクリアされてしまうので注意すること。

# コード

```batchfile:コード
@echo off

set AWS_ACCESS_KEY_ID=
set AWS_SECRET_ACCESS_KEY=
set AWS_SESSION_TOKEN=
set AWS_DEFAULT_REGION=ap-northeast-1

set USERNAME="username"

set AUTHCODE=
set /p AUTHCODE=Please input authentication code:

for /f "tokens=1-5 usebackq" %%i in (`aws sts get-session-token --serial-number "arn:aws:iam::nnnnnnnnnnnn:mfa/%USERNAME%" --output text --token-code "%AUTHCODE%"`) do (
    @set AWS_ACCESS_KEY_ID=%%j
    @set AWS_SECRET_ACCESS_KEY=%%l
    @set AWS_SESSION_TOKEN=%%m
)

aws ssm start-session --target i-xxxxxxxxxxxxxxxxx

set AWS_ACCESS_KEY_ID=
set AWS_SECRET_ACCESS_KEY=
set AWS_SESSION_TOKEN=
set AWS_DEFAULT_REGION=ap-northeast-1
```

# ピックアップ

もうこの記事で書くことはあまりないけど以下だけ。

## 環境変数の初期化とクリア

```batchfile
set AWS_ACCESS_KEY_ID=
set AWS_SECRET_ACCESS_KEY=
set AWS_SESSION_TOKEN=
set AWS_DEFAULT_REGION=ap-northeast-1
```

不本意なID/KEYで接続いってもいけないので初期化して、最後に使い終わったらクリアのために。

# Session Manager のコマンド例

上記コードにある

```
aws ssm start-session --target i-xxxxxxxxxxxxxxxxx
```

の部分。これを↓に変更するとポートフォワードが可能になる。

日本語のサイトにあるコマンド構文だと"localPortNumber"でエラーになったので以下の構文にする必要がある。(日本語サイトから言語を英語に切り替えた後に表示されるページの構文でもエラーになったので注意)

## HTTP

```
aws ssm start-session --target i-xxxxxxxxxxxxxxxxx --document-name AWS-StartPortForwardingSession --parameters "portNumber"=["80"],"localPortNumber"=["8080"]
```

## SSH

```
aws ssm start-session --target i-xxxxxxxxxxxxxxxxx --document-name AWS-StartPortForwardingSession --parameters "portNumber"=["22"],"localPortNumber"=["8022"]
```


以下の記事にもあるが、私はTera Term使いなのでSession Managerを駆使しつついつものTera Termが使えるので便利。(ファイル転送もD＆D！)

Tera Termの便利な機能(自動ログ採取、ログ表示、ファイル送受信、接続先のリスト表示、同時操作) - Qiita
https://qiita.com/SECUAL_masa/items/afed756a05c893a3651e
git rebase - i でmergeされたコミットを見たいときに使う「p」コマンドについて

参考
https://dackdive.hateblo.jp/entry/2014/09/21/122200

ちなみに上の記事では書いてないですが、以下のようにハッシュ値でコミットに遡ることができます。
(ハッシュ値とは、`git log ---oneline`で出る黄色の文字)
```
git rebase - i 8dadj9
```

このときに、自分はmergeされたコミットに遡れないことに気がついた。
出てこない。なぜだ？

そこで、調べてみると以下のコマンドでmergeの取り込みの際に使用したブランチも確認できる。
```

git rebase -i -p 8dadj9

```
Amazon File Cache とは

## 勉強前イメージ

聞いたことないかも
file cacheってことはs3の前に置いたりする？

## 調査

### Amazon File Cache とは

2022/09/30 に一般提供が開始されたサービスで、ファイルサーバに対するキャッシュのサービスになります。
初期費用はかからず、キャッシュストレージ容量とメタデータのストレージ容量で費用が決定します。
Amazon File Cache以外ではs3のリクエスト費用などデータの送信や転送にかかわる費用は発生します。

現在サポートしているファイルサーバは以下になります。

- s3バケット
- NFSサーバ
	- Amazon FSx for OpenZFS
	- Amazon FSx for NetApp ONTAP
- オンプレのNFSサーバ(NFS v3)

### Amazon File Cache 対応リージョン

対応しているリージョンは以下になります。
東京リージョンも入っています。

- 米国東部(オハイオ)
- 米国西部(オレゴン)
- 米国東部(バージニア北部)
- アジアパシフィック(シンガポール)
- アジアパシフィック(シドニー)
- アジアパシフィック(東京)
- カナダ(中部)
- ヨーロッパ(フランクフルト)
- ヨーロッパ(アイルランド)
- ヨーロッパ(ロンドン)

###  Amazon File Cache の画面

Amazon File CacheはマネジメントコンソールではAmazon FSxの一部として扱われ、
`Amazon FSx > キャッシュ` でAmazon File Cacheを確認することが出来ます。

![1Amazon FSx - Google Chrome 2022-10-04 18.50.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/4d417e21-e5a2-0879-648e-943fe1caba33.png)

## 勉強後イメージ

新サービス！！
s3とかについてのキャッシュならめっちゃ需要ありそう・・！

## 参考

- [[新サービス] Amazon File Cache が一般提供されました](https://dev.classmethod.jp/articles/amazon-file-cache-generally-available/)
- [Amazon File Cache is now generally available](https://aws.amazon.com/jp/about-aws/whats-new/2022/09/amazon-file-cache-generally-available/)
- [Amazon File Cache – オンプレミスファイルシステムのための AWS のハイパフォーマンスキャッシュ](https://aws.amazon.com/jp/blogs/news/amazon-file-cache-a-high-performance-cache-on-aws-for-your-on-premises-file-systems/)
バッチファイル内でコマンドの実行結果を複数の変数に取りだし利用する

# はじめに

久しぶりにWindowsのバッチファイルで、、、

1. コマンドを実行
1. 上記1の実行結果を取得して次のコマンドに引き継いで実行

なんてことをしたくなった。

この時、

* 手順1の実行結果には複数の情報がある。
* その複数の情報を次のコマンドの引数(変数1、変数2、変数3)といった形で渡したい。

とも。

これをいざ実現しようと思ったら「複数の情報」→「変数1/変数2/変数3」に取りだすことに苦労したのでまとめる。

# やりたいこと

```
コマンドの実行結果(複数の情報)を取りだし変数1/変数2/変数3に取りだす。
```

# サンプルコード

```batchfile:サンプルコード
@echo off

rem for /f "tokens=1-5* usebackq" %%i in (`echo aaa bbb ccc ddd eee`) do echo %%i %%j %%k %%l %%m

for /f "tokens=1-5* usebackq" %%i in (`COMMAND`) do (
    @set VAR1=%%j
    @set VAR2=%%l
    @set VAR3=%%m
)

rem echo VAR1=%VAR1%
rem echo VAR2=%VAR2%
rem echo VAR3=%VAR3%

NEXTCOMMAND %VAR1% %VAR2% %VAR3%
```

# ピックアップ

```batchfile:お試しロジック
rem for /f "tokens=1-5* usebackq" %%i in (`COMMAND`) do echo %%i %%j %%k %%l %%m
```

今回の要件の実現可否を調べた時にヒットするやり方は上記のようにechoを使う方法だった。
これを変数1/変数2/変数3に設定する話は後述するとして、ここではこの構文に不慣れな方向けに説明したい。

上記のコマンドを日本語で説明すると、

```
COMMANDの実行結果を空白またはタブで5個分を区切り、その5つを表示(echo)する。
```

となる。さらに分割して説明していこう。

## tokens

tokensが”5個分を区切り"に相当する。
サンプルコードとその結果で挙動をみていく。

```batchfile:sample.bat
@echo off

for /f "tokens=1 usebackq" %%i in (`echo aaa bbb ccc ddd eee`) do echo i=%%i j=%%j k=%%k l=%%l m=%%m

for /f "tokens=2 usebackq" %%i in (`echo aaa bbb ccc ddd eee`) do echo i=%%i j=%%j k=%%k l=%%l m=%%m

for /f "tokens=1,2 usebackq" %%i in (`echo aaa bbb ccc ddd eee`) do echo i=%%i j=%%j k=%%k l=%%l m=%%m

for /f "tokens=1-3 usebackq" %%i in (`echo aaa bbb ccc ddd eee`) do echo i=%%i j=%%j k=%%k l=%%l m=%%m

for /f "tokens=1-3* usebackq" %%i in (`echo aaa bbb ccc ddd eee`) do echo i=%%i j=%%j k=%%k l=%%l m=%%m

for /f "tokens=1-5 usebackq" %%i in (`echo aaa bbb ccc ddd eee`) do echo i=%%i j=%%j k=%%k l=%%l m=%%m
```

```text:sample.batの結果
C:\Users\USER>D:\tools\sample.bat
i=aaa j=%j k=%k l=%l m=%m           ・・・ 1個目だけ
i=bbb j=%j k=%k l=%l m=%m           ・・・ 2個目だけ
i=aaa j=bbb k=%k l=%l m=%m          ・・・ 1,2個目を
i=aaa j=bbb k=ccc l=%l m=%m         ・・・ 1～3個目を
i=aaa j=bbb k=ccc l=ddd eee m=%m    ・・・ 4個目以降はまとめて4つ目に
i=aaa j=bbb k=ccc l=ddd m=eee       ・・・ 1～5個目を
```

コマンドの実行結果とtokensの書き方、%%i ～ %%mへの格納のされ方を理解しておこう。

## usebackq と \`COMMAND\`

バッククォート(`)で囲まれたCOMMANDを実行する的な意味合いになるようなのでこの書き方はセット。

## %%i ～ %%m

``%%i in (`COMMAND`)``の`%%i`は`%%a`でもよく、`do`の後で記載する変数がそのアルファベットに続く形をとる必要がある。

`%%a`だと
``%%a in (`COMMAND`) do echo %%a %%b %%c %%d %%e``
とする必要がある。

## delims

今回のサンプルは区切り文字が空白で、デフォルトも空白またはタブであるため省略したが、カンマ(,)の場合は以下のようになる。

```batchfile:サンプルコード2
@echo off

for /f "tokens=1-5 usebackq delims=, " %%i in (`echo aaa,bbb,ccc,ddd,eee`) do echo i=%%i j=%%j k=%%k l=%%l m=%%m
```

```text:サンプルコード2の結果
C:\Users\USER>D:\tools\sample2.bat
i=aaa j=bbb k=ccc l=ddd m=eee
```

`"... delims=, "` である必要に注意(カンマの後ろに半角空白)。
`"... delims=,"` だと正常に区切られなかった。

# 実行結果を変数に取りだす

さて本題。

```
for /f "tokens=1-5* usebackq" %%i in (`COMMAND`) do (
    @set VAR1=%%j
    @set VAR2=%%l
    @set VAR3=%%m
)
```

上記のロジックでCOMMANDの実行結果から複数の情報を変数1(VAR1)/変数2(VAR2)/変数3(VAR3)に取りだしている。取りだしているのは先頭から5個分の中の2番目(%%j)と4番目(%%l)と5番目(%%m)の3つ。

```
for /f "tokens=2 usebackq" %%i in (`COMMAND`) do @set VAR1=%%j
```

変数に取りだしたい情報が1個の場合は上記のような書き方もできる。(他のサイトで見るやり方)

# さいごに

上記の内容を駆使してやりたかったことも紹介したいので次の記事で公開したいと思います！
EC2からElastiCacheへ接続する方法

## はじめに
検証で、EC2からElastiCacheへ接続することになった。
その際にハマってしまったことを備忘録として記す。

## 用意するもの
- EC2
- ElastiCache

### 準備
- EC2の作成についてはググれば出てくると思うので割愛
- ElastiCacheの作成は、AWSコンソール上から作成

## 手順
### 1. EC2へログイン

localからログインしましょう
尚、詰まってしまった場合は以下を参照

https://qiita.com/ashley123/items/9b93b63833118456b2a9


### 2. ElastiCacheのコンソール上からクラスターのエンドポイントを確認
作成したElastiCacheのノード欄の横にエンドポイントが表示されます。それをコピーしましょう

```
##エンドポイント例
test-001.hogehoge.0001.apen1.cache.amazonaws.com:6379
```

### 3. EC2からエンドポイントへ接続前準備
[資料](https://aws.amazon.com/jp/premiumsupport/knowledge-center/elasticache-connection-test/)を参考にしながらEC2内で実施しました。
※今回はLinux2のEC2を作成していたので、以下手順を用いています。

```
$sudo amazon-linux-extras install epel -y
$sudo yum install gcc jemalloc-devel openssl-devel tcl tcl-devel -y
$sudo wget http://download.redis.io/redis-stable.tar.gz
$sudo tar xvzf redis-stable.tar.gz
$cd redis-stable
$sudo make BUILD_TLS=yes
```


### 4. EC2からElastiCacheへ接続
EC2からElastiCacheへ接続します

```
src/redis-cli -h test-001.hogehoge.0001.apen1.cache.amazonaws.com -p 6379
```

## ハマったこと
ここにきて接続できず...
色々資料を探すと、セキュリティグループがEC2と同じものを付けていると接続しないとコメントがあるのを見つけました。（今回の検証でもEC2と同じセキュリティグループ使っていたので修正）

## 解決策
`EC2`と`ElastiCache`は別のセキュリティグループを付与すると良さそう


## 資料
- [Amazon ElastiCache Redis または Memcached クラスターへの接続をテストするにはどうすればよいですか?](https://aws.amazon.com/jp/premiumsupport/knowledge-center/elasticache-connection-test/)
- [ElastiCache for Redis クラスターに接続できないのはなぜですか。](https://aws.amazon.com/jp/premiumsupport/knowledge-center/elasticache-redis-cluster-fix-connection/)
- [知ってて損はないRedisコマンド](https://shimer-system.com/blog/archives/349#toc3)
link_toメソッド

# link_toメソッドとは

リンクを作成するためのヘルパーメソッドです。HTMLのaタグの代わりに使用できます。
ビューファイルでは、以下のように記述します。 タグとして出力するため、<%= %>で囲う必要があります。

```:リンク先をURLで指定する場合
<%= link_to 'リンクに表示する文字', 'リンク先のURL' %>
[例]
<%= link_to 'Qiita', 'https://qiita.com/' %>
```

```:リンク先をパスで指定する場合
<%= link_to 'リンクに表示する文字', 'パス', method: :HTTPメソッド %>
[例]
<%= link_to 'ログイン', new_user_session_path, class: "login" %>
<%= link_to '新規登録', new_user_registration_path, class: "sign-up" %>
<%= link_to '新規投稿', '/posts/new', method: :GET %>
```

:::note
link_toメソッドでパスを指定する場合、何も指定しなければデフォルトでGETメソッドが設定されます。
したがって、GETメソッドの指定を省略して記述することができます。
:::
JetsonAGX Xavier の開発環境を構築する

# はじめに
<!-- 概要 -->
JetsonAGX Xavier　jetpack5.0
SSD装着済み　

の開発環境を作る際に行った作業の備忘録

# 目次

1. [WiFi環境構築](#Chapter1)
1. [SSDマウント](#Chapter2)
1. [VScodeのインストール](#Chapter3)
1. [参考文献](#reference)

<!-- 各チャプター -->
<a id="#Chapter1"></a>
# WiFi環境構築
以下のリンクにある、TP Linkを使用する為に、ドライバを入手する。

https://www.googleadservices.com/pagead/aclk?sa=L&ai=DChcSEwiHy6LZ1sX6AhWGJGAKHfb1CQQYABAEGgJ0bQ&ohost=www.google.com&cid=CAESbeD28P9LeM8dbOnJA-alxdmjnbz_xlKI01HkQjncF10FaoFVsZvEncuGRDzMIK1yOfHBUZDf7vSO29m5UDWFnb2sfRWCPBAkXkKFNwlxnCFZ4gczdso-93D72GmQpsCvcNmjBeep89UqVMV3u9U&sig=AOD64_3TyqEwc9lexTfj-r8CHs35FT7yxw&ctype=5&q=&ved=2ahUKEwjDsJvZ1sX6AhX-tlYBHWuWAngQ9aACKAB6BAgCEA4&adurl=

まず、dkmsを入手
~~~
sudo apt update
sudo apt install dkms build-essential linux-headers-generic
sudo apt install git
~~~
次に、rtl8812auドライバ(TPLinkのnanoに内蔵されているチップ名称)
~~~
git clone https://github.com/aircrack-ng/rtl8812au.git
cd rtl8812au
sudo make dkms_install
reboot
~~~
<a id="#Chapter2"></a>
# SSDマウント
~~~
cd ~/
sudo mkfs.ext4 /dev/nvme0n1
sudo mkdir nvme
sudo mount /dev/nvme0n1 /home/jetson/nvme
~~~
viやvimで /etc/fstabにデバイスを追加
~~~
/dev/nvme0n1 /home/jetson/nvme ext4 defaults 0 1
~~~

<a id="#Chapter3"></a>
# VScodeのインストール

https://packages.microsoft.com/repos/code/pool/main/c/code/code_1.65.2-1646922911_arm64.deb
~~~
sudo dpkg -i code_1.65.2-1646922911_arm64.deb
~~~
# 参考文献
https://qiita.com/fcc-tsuchiya/items/1a35a28bf695a79c3dfc
https://qiita.com/fcc-tsuchiya/items/36eba9b5bfebf897fbf6
GitHubにてSSH接続で詰まった話し


## 概要

タイトル通りになるが、新しいプロジェクトにアサインした際に自分のPCではなく支給されたPCにて久しぶりにSSH接続をした時にハマったので自分のの備忘録として記載

### 行った内容
ますはGitHubのSSHの設定を一度削除してからやり直しを前提にする

```
$ ssh -T git@github.com

# これが返ってきたら成功
# Hi ○○ You've successfully authenticated, but GitHub does not provide shell access.
```
🔼認証できなくて、うまくいかなかった。


```
# 上から順に実行🔽

$ rm -rf ~/.ssh
# まずは元のファイル達を消す

$ mkdir ~/.ssh
# ディレクトリを作成する

$ cd ~/.ssh
# 移動

$ ssh-keygen -t rsa -f id_rsa_github
# 引用を参照

$ vi config
# 設定ファイルを記述

pbcopy < id_rsa_github.pub
# ゴミが無いようにコピーするための便利なコマンド
```

引用🔽
> - ssh-keygen ... 秘密鍵と公開鍵を生成するLinuxコマンド。
> - -t <暗号化タイプ>オプション ... 暗号化形式を指定する。暗号化タイプは下記URLを参照。
> - -f <ファイル名>オプション ... ファイル名を指定する。指定しない場合「id_rsa」と言う名前になる。
> - -C <コメント>オプション ... コメントを記述。ここで指定したコメントは鍵の最後に表示される。
> - デフォルト値は、「Macのユーザー名@Macのコンピューター名.local」となります。
---

### 結果的に...

```
cat config
#中身を見ると

Host github
  HostName github.com
  IdentityFile ~/.ssh/id_rsa_github
  User git

↓↓↓↓↓↓

Host github.com
  HostName github.com
  IdentityFile ~/.ssh/id_rsa_github
  User git
```
これで解決とな。。。

-- 参考記事 --
https://blog.cloud-acct.com/posts/u-github-ssh/

https://ormcat.net/blog/20210509_github-denied-publickey/#github-%E3%81%B8%E3%81%AE-ssh-%E6%8E%A5%E7%B6%9A%E3%81%A7-permission-denied-publickey-%E8%A8%80%E3%82%8F%E3%82%8C%E3%81%9F%E3%81%AE%E3%81%A0%E3%81%8C
DatabricksのSQLのセルからPythonの変数にアクセスする

こちらでも紹介されている意外に便利な機能、自分でも試してみました。

https://qiita.com/manabian/items/a7f03e047d82259df313

アプローチはPythonのセルで[spark.conf](https://spark.apache.org/docs/latest/configuration.html)のプロパティを設定し、SQLのセルから参照するというものです。

# Pythonセルで変数を設定

データベース名とテーブル名を設定するものとします。`spark.conf.set`にプロパティ名と値をペアで設定します。

:::note info
**注意**
ここで第一引数に設定するプロパティ名は`.`で区切ったプレフィックスを指定してください。以下の例ではプレフィックスは`c`ですが、任意の文字列を指定ください。
:::

```py:Python
%python
spark.conf.set('c.database_name', '20210712_demo_takaakiyayoi')
spark.conf.set('c.table_name', 'eki_movement')
```

# SQLセルで変数を参照

SQLのセルからプロパティの値を参照します。なお、こちらのデータベースやテーブルが存在することを前提としています。

```sql:SQL
%sql
SELECT * FROM ${c.database_name}.${c.table_name}
```

テーブルを参照することができました。
![Screen Shot 2022-10-04 at 18.01.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/bb1da240-2000-77be-41e0-2b0984abbf95.png)

### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)
ローカルで証明書のエラーがでないちゃんとしたSSLを設定する方法

エラーの出るオレオレ証明書を使っていると、色んな所で「証明書のエラーだよ！」って出て困ります。
最近は、SSLじゃないと使えないよ〜！って機能も増えてきて困りますね。

そういう時はmkcertで、ブラウザから有効な証明書と扱われるオレオレ証明書をちゃんとインストールしましょ。

## mkcertで有効な証明書を発行する

https://web.dev/i18n/ja/how-to-use-local-https/

### 証明書を『foo.pem』、秘密鍵を『bar-key.pem』という名前で発行
$ mkcert -cert-file foo.pem -key-file bar-key.pem localhost


## 開発環境で使う

nuxt.config.jsの例

```
https: {
      key: fs.readFileSync(`/pathto/cert/localhost.key`),
      cert: fs.readFileSync(`/pathto/cert/localhost.crt`),
    },
```

これで、ブラウザでアクセスしても警告の出ないSSLサイトが使えます。やったね！
プール、浴槽、などでの、感電事故対策


#### プール、浴槽、などでの、感電事故対策が不十分です！

一般的な水中照明でなく　温泉、プールなど、　
特に人が触れる　可能性の高いものに限定される仕様に限ると思いますが、
規模は大きいのですが、私の過去の現場では、 混触防止トランス、
地絡感知警報機などが付いた現場が、ほとんどでした。

#### 　最近の工事ではプール、浴槽、などでの、感電事故対策が不十分です！

こちらの事故は充電用コンセントを、 混触防止防止トランスで絶縁することで防げます！

https://kodomonoanzen.jp/new/14%E6%AD%B3%E5%B0%91%E5%A5%B3%E3%81%8C%E6%B5%B4%E6%A7%BD%E3%81%A7%E6%84%9F%E9%9B%BB%E6%AD%BB%E3%80%82%E3%82%B9%E3%83%9E%E3%83%9B%E5%85%85%E9%9B%BB%E4%B8%AD%E3%80%82%E3%83%86%E3%83%AC%E6%9C%9D%E3%81%A7/

https://hitachi-ies.force.com/web/s/article/trans5228

#### プールサイドの音響機器・事故防止対策　（SSR株）
https://www.ssr-makasero.co.jp/wp-content/themes/ssr_ver05/img/product/powersystem/document.pdf
https://www.ssr-makasero.co.jp/company/


##### 現在は漏電遮断機の信頼度が高いので、こちらで防ぐ方が一般的なのかもしれません。
プール設備使用前点検において漏電遮断器の動作不良を発見

https://www.sdh.or.jp/information/casestudy/prevention/200.html


https://detail-infomation.com/short-circuit-and-ground-fault-and-electric-leakage/

https://electric-facilities.jp/denki7/ti/009.html

##### 以下 Yamagiwa社販売の　水中照明用トランスは混触防止トランスを使っています

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/378482/38ce31d0-4832-d7ef-8696-343decbafcce.png)



昔は　規模の大きな音楽噴水など　地絡感知警報機を　付けていました。

https://www.fa.omron.co.jp/product/special/protection_relay/basic/02/02.html

https://www.hikari-gr.co.jp/products/search/product02/list02/item_63
Go Moduleって何

# はじめに
GoでDockerでGoサーバーを立てるとき、改めてGo Moduleって何となったので調べたことをまとめます。

# Go Moduleとは
パッケージ(Package)をまとめたもの。パッケージはコードをまとめるもの。すべてのコードはパッケージに入っている。
モジュールがパッケージの依存関係を管理する。
例えばAパッケージの関数がBパッケージの関数を使用するとする。
つまり、AパッケージはBパッケージがないと動かない、AはBに依存しているということになる。

補足:goはmainパッケージのmain関数から処理が始まる。

# go mod でGoモジュールを作成する
goプログラムが入っているフォルダ内で、以下のコマンドを実行することでモジュールが作成できる。
ユニークな名前は、公開する場合はgithubのリポジトリ名、
非公開の場合はローカルでユニークな名前を付ける。
ユニークな名前とは、世界(非公開の場合はローカルで)同じモジュール名がないようにすること。
モジュールを参照するとき、同じ名前のモジュールがあったらどっちのモジュールを参照すべきかわからなくなるため、ユニークな名前を付ける。
``` 
go mod init ユニークな名前
```

以下のようなgo.modファイルがGoのソースフォルダのルート直下に作成される。

``` go.mod
module ユニークな名前
 
go 1.18
```

フォルダ構成は以下の例が挙げられる。
ルート直下のgo.modがGoProgram内のmainパッケージ、testパッケージをまとめて管理しているイメージ。

```
GoProgram/
├sample/
│　　　├main.go ※package main
│　　　└test/
│        └test.go ※package test 
└go.mod
```

参考記事
* [GolangでModule(モジュール)について説明して、どう使えるか紹介します。](https://dev-yakuza.posstree.com/golang/module/)
* [GolangでPackage(パッケージ)について詳しく説明して、使う方法についても説明します。](https://dev-yakuza.posstree.com/golang/package/)

# go modに記載してあること
requireやreplaceなど

参考記事
* [オサムテック Go言語 – Go Modules](https://osamu-tech-blog.com/go-go-modules/)

# go.sumファイル
go getの後に作成される

参考記事
* [【Go】パッケージ/モジュールやgo modコマンドについてまとめ](https://blog.framinal.life/entry/2021/04/11/013819)


# 「go get」 「go mod tidy」 「go install」コマンドについて
go getで標準以外のリポジトリをインストールできる。
go mod tidyで外部に作成されたモジュールをダウンロードする。
標準以外を使用する場合はgo mod tidy必須かと。
詳しくは使用するときに調べる。

参考記事
[go mod完全に理解した](https://zenn.dev/optimisuke/articles/105feac3f8e726830f8c)
【Dockerfile】ADDとCOPY、CMDとENTRYPOINTの違い



## ADDとCOPYの違い
- ADD
    - .tarの展開とコピーが同時にできる
    -  外部ファイルのダウンロードができる
- COPY
    - コピーしかできない


## どっちを使えば良いのか？
- .tarを展開したいなど明確な理由がない場合は **COPYで良い**
    - ADDだと、いろいろ機能がつきすぎて透明的では無いため
    - 公式のベストプラクティスにもそう書いてある
        - [https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#add-or-copy](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#add-or-copy)

## CMDとENTRYPOINTの違い
- DockerfileにCMDしか書かない場合はFROMで指定するイメージで利用されるENTRYPOINTに注意する必要がある。
 - CMDに書かれたコマンドが意図通りに動作するとは限らないため
 - 不安なら自分でENTRYPOINTで指定してあげると良い
     - 複数にENTRYPOINTがある場合、1番最後に書かれたENTRYPOINTが有効になる
【Swift】RxGestureでのスワイプ検知がまじ簡単

# はじめに
いまRxSwiftの勉強中でして、RxSwiftを使ってアプリを1個リリースするという目標を立てて頑張っています。
勉強中に出会ったRxGestureがめっちゃ便利だったので記録しておきます。

# スワイプの監視
### 上方向スワイプ
```swift
view.rx
    .swipeGesture(.up)
    .when(.recognized)
    .subscribe(onNext: { _ in
        print("上方向にスワイプしました")
    })
    .disposed(by: disposeBag)
```
### 下方向スワイプ
```swift
view.rx
    .swipeGesture(.down)
    .when(.recognized)
    .subscribe(onNext: { _ in
        print("下方向にスワイプしました")
    })
    .disposed(by: disposeBag)
```
### 右方向スワイプ
```swift
view.rx
    .swipeGesture(.right)
    .when(.recognized)
    .subscribe(onNext: { _ in
        print("右方向にスワイプしました")
    })
    .disposed(by: disposeBag)
```
### 左方向スワイプ
```swift
view.rx
    .swipeGesture(.left)
    .when(.recognized)
    .subscribe(onNext: { _ in
        print("右方向にスワイプしました")
    })
    .disposed(by: disposeBag)
```

# おわり
いままでSwiftUIを使ってきて、SwiftUIでスワイプ検知しようと思うと自前で実装しないといけなかったので結構大変だった記憶があります。
RxGestureには本当に感動しました笑