OmniAICreator/Qiita-1.07M huggingface dataset:
OpenVPN Accsss Server (OpenVPN AS) の設置メモ

## この記事について

* `OpenVPN` を設置した際のメモ書きです。
* `OpenVPN` は無料ですが設定が難しいので `OpenVPN Access Server`　を使います。
* 無料で２ユーザまで使え、それ以上は有料になります。
* `docker` がインストールされていることが前提になります。

## 1. OpenVPN のアカウントを作成

`OpenVPN Access Server`を使うためには`OpenVPN`でアカウントを作成する必要があります。

https://openvpn.net/access-server/


## 2. Activation Key を取得

`Activation Key` をコピーしておきます。後の工程で使います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1038343/e42adb4d-1c1b-f932-33e0-c7a5e20e2cbb.png)


## 3. docker-compose.yml を作って起動

```yaml:docker-compose.yml
version: "2.1"
services:
  openvpn-as:
    image: ghcr.io/linuxserver/openvpn-as
    container_name: openvpn-as
    cap_add:
      - NET_ADMIN
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Asia/Tokyo
      - INTERFACE=eno1 # optional
    volumes:
      - ./config:/config
    ports:
      - 943:943
      - 9443:9443
      - 1194:1194/udp
    restart: unless-stopped
```

```sh:起動
docker-compose up -d
```

## 4. 設定

ブラウザで管理画面に `https` で、ポート`943`へアクセスする。
例） https://localhost:943/

### ログイン

ユーザーは `admin`、パスワードは `password`です。
（後の工程で必ず変更しましょう）


### アクティベーション

前の工程で取得した`Activation Key`を貼り付けます。（画面はアクティベーション済みです）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1038343/2ed2936d-6569-1004-aba4-4ab796faed8b.png)


### Network Settings

`Hostname or IP Address` をWAN側のドメインかIPアドレスを設定して`Save Settings` を押下します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1038343/f1037a0c-e5e9-6901-a91a-d6d1af40f2b5.png)

### VPN Settings

LANのサブネットとDNSを設定して`Save Settings` を押下します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1038343/90573d82-4a1b-c145-1732-9ef9001538bd.png)

インターネットアクセスを`VPN`経由にしたくない場合は `Should client Internet traffic be routed through the VPN?` を `No` に設定します。




## 5. ユーザー追加

ユーザー名とパスワードを設定して `Save Settings` を押下します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1038343/858da6c9-2d72-c550-c1ce-9ea0b18ce1df.png)


## 6. admin パスワード変更

```sh
docker exec -it openvpn-as passwd admin
```
`Enter new UNIX password:` と聞かれるので設定します。（2回入力）
以降は、管理画面の`admin`はここで設定したパスワードを使用しあｍす。


## 7. ポートフォワーディング

ルータの設定で下記のポートを転送する。
* 943/tcp
* 9443/tcp
* 1194/udp


## 8. クライアントアプリのインストール

ユーザアカウントで管理画面にログインするとインストーラをダウンロードすることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1038343/b493e203-8abf-e1b4-45a0-e12878ffa92f.png)


## 9. クライアントアプリの接続設定

### 接続プロファイルを生成して`ovpn`ファイルをダウンロード

ユーザアカウントで管理画面にログインして `Profiles Management` 画面に移動する。
`Create` を押下すると`ovpn`ファイルがダウンロードされます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1038343/21a1c76e-4a81-4428-0e8a-706b48bb3324.png)


### クライアントアプリで`ovpn`ファイルをインポート

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1038343/d7bb6239-8752-e1ef-5703-bc3779ba7081.png)
FonTool 無償配布キャンペーン

FonToolはiPhoneをバックアップできるWindows向けのソフトウェアです。iOS版もあります。キャンペーンではリモートソフトとWindowsのバックアップも無料配布されています。

キャンペーン期間：
2023-10-06まで
キャンペーンサイト:
https://www.fonetool.com/partners/new-iphone-release-giveaway-6154.html
![FoneTool giveaway.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3561585/ba8e6d4f-e97b-f7d6-1470-b7a381cc0904.png)
Homebrew でのビルドエラーの対処方法

macOSでよく使用されるパッケージマネージャであるHomebrewは通常、コンパイル済みのバイナリをダウンロードしてインストールするので、Formula（パッケージ）のインストール・更新を手軽に行えます。

しかし、macOSのバージョンが古い場合、Formulaのインストール・更新時にソースコードをクローンして手元でビルドする必要があります。その際、コンパイラとソースコードの相性など、さまざまな原因でビルドが失敗することがあります。
この記事では、Homebrewでビルドエラーが起こったときの対処方法を紹介します。

## ビルドエラーに対処するために
通常、Formulaをインストール・更新するには`brew install <Formula名>`または`brew upgrade <Formula名>`コマンドを実行します。その際に、オプションとして`-d`を指定すると、ビルドが失敗した時に対処を選ぶプロンプトを表示させることができます。

選択できるコマンドは、以下の通りです。
  - `1. raise`: `-d`を指定しなかったときと同じ動作（エラー出力してビルドを中断し、クリーンアップ）をします。
  - `2. ignore`: エラーが発生した工程をスキップします。
  - `3. backtrace`: Homebrew自体のどこでエラーが発生したか、スタックトレースを表示します。
  - `4. irb`: Ruby インタプリタ(`irb`)を起動します。
Formulaファイル（後述）を見ながら、対話的にビルドを進めることができます。`irb`が終了すると、エラーが発生したところからビルドが再開されます。
  - `5. shell`: 既定のシェルを起動します。
ソースコードを直接変更する必要があるときなどに便利です。シェルが終了すると、再び5つの選択肢が表示されます。

**`-d`オプションを指定する際は、あわせて`-v`オプションも指定しましょう。コンパイラの出力がコンソールに表示されるようになるので、原因の特定に役立ちます。**

## Formulaファイルを確認して、問題箇所を探り当てる
Formulaファイル（`/usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula`内にFormulaと同名で存在します）には、Formulaの基本情報や依存関係、ビルドツールに渡す引数などが記載されています。問題がそこにあると考えられる場合は、適宜修正します。

`brew edit <Formula名>`を実行すると、`vim`でFormulaファイルが開きます。
- `depends_on: "<Formula名>"`: 必要な別のFormula（ライブラリなど）を指定します。
 - `def build`〜`end`内: ビルドのための手順が記述されています。

## ソースコードを修正する
場合によっては、ソースコードを直接修正する必要が出てくるかもしれません。その際は、コンソールに表示されたコンパイラのエラーメッセージ等を頼りに、自力で調べながら修正していく必要があります。方法はさまざまですが、大方、次の手順で行うと簡単でしょう。

1. ビルド失敗時に表示されるプロンプトで、`5`を選択してシェルを起動します。
2. `open -R`を実行して、Finderでビルド中のソースコードのルートディレクトリを開きます。
3. エラーメッセージなどを頼りに必要なソースファイルを修正し、保存します。
4. `Ctrl+D`を押してシェルを終了します。
5. `4`を選択して、`irb`を起動します。
6. 何も入力せず`Ctrl+D`を押します。`irb`が終了し、ビルドが続行されます。

ビルドエラーが起こったときは、これらの手順を参考にするとよいでしょう。
openCVで画像の一部分を拡大

# はじめに
python*openCVでの画像の一部を拡大表示するためのプログラムです。

# 問題
openCVを使って以下のような画像を表示し、横断歩道の四隅をマウス操作でクリックする際に
画面いっぱいまでしか拡大できず、さらに拡大したいと思っていました。
なので、画像の中心は変えずに、倍率を指定して拡大するようなプログラムを作成しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3561529/cf78113b-c1a2-d0d5-2ef2-30ff74899976.png)


# 解決方法
```
import cv2

# 画像読み込み
input_image_path = "input_image.jpg"  # 入力画像のファイルパスを指定してください
output_image_path = "output_image.jpg"  # 出力画像のファイルパスを指定してください
scale_factor = 2  # 拡大倍率（縦も横も元の画像の半分になるようにするため、2を指定）

# 画像を読み込む
image = cv2.imread(input_image_path)

# 画像の高さと幅を取得
height, width = image.shape[:2]

# 中心座標を計算
center_x = width // 2
center_y = height // 2

# 切り抜く領域の左上と右下の座標を計算
left = int(center_x - width / (2 * scale_factor))
right = int(center_x + width / (2 * scale_factor))
top = int(center_y - height / (2 * scale_factor))
bottom = int(center_y + height / (2 * scale_factor))

# 切り抜いた領域を拡大
cropped_and_scaled_image = image[top:bottom, left:right]

# 拡大後の画像を保存
cv2.imwrite(output_image_path, cropped_and_scaled_image)

# 表示（オプション）
cv2.imshow("Cropped and Scaled Image", cropped_and_scaled_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
```

ちなみに
left = int(center_x - width / (2 * scale_factor))
は intがないと、きりの悪い倍率の時にうまくいかないのでその対策です。


# おわりに
chatGPTを使ったら秒でしたが、一回のやり取りではうまくいかなかったので
もし誰かの時短になれればと思っています。
【非同期処理】コールバック関数とは

コールバック関数は、他の関数の引数として渡される関数です。
この関数は、ある処理が終了した時点で「呼び出されます」。

## コールバック関数の例

```javascript
function doSomething(callback) {
  // 何かの処理をします (例: データを取得)
  const data = "Hello from doSomething!";
  
  // 処理が完了したら、コールバック関数を呼び出します
  callback(data);
}

doSomething(function(result) {
  console.log(result);  // "Hello from doSomething!"
});
```

上の例では、`doSomething関数`にコールバック関数として無名関数を渡しています。
`doSomething関数`は処理を終了した後、そのコールバック関数を呼び出しています。

### コールバック関数の引数名
```javascript
function doSomething(callback) {
  // ...
  callback(data);
}
```
ここでのcallbackは、ただの引数の名前です。
名前として`aaa`や`func`や`handler`など、他の任意の名前を使用することもできます。
しかし、この関数がコールバックを受け取る関数であることを示すために、多くの開発者は`callback`という名前を選びます。

もし`aaa`に変更した場合、関数内の`callback(data);`も`aaa(data);`と変更する必要があります。


### doSomething関数の呼び出しについて
```javascript
doSomething(function(result) {
  console.log(result);  // "Hello from doSomething!"
});
```
この記述では、`doSomething関数`を呼び出しています。
そして、`doSomething関数`の引数として無名関数（またはラムダ関数、またはアロー関数の特定の形式）を渡しています。

`function(result) { ... }`は関数です。これは、`doSomething関数`の中でコールバックとして使用される関数を定義しています。
この関数は、`doSomething`の中の`callback(data);`によって、dataとして`"Hello from doSomething!"`が渡されることで呼び出されます。

要するに、`doSomething(function(result) { ... });`の形式での記述は、「doSomething関数を呼び出し、この関数が完了したら、この無名関数を実行してください」という意味になります。

この無名関数は、コールバック関数としての役割を果たします。

### doSomething関数の呼び出しの無名関数の引数名

```javascript
doSomething(function(aaa) {
  console.log(aaa);  // "Hello from doSomething!"
});
```

上記のコードでも問題ありません。
ここでの`aaa`は、コールバック関数の引数の名前として定義されているだけなので、何を使っても構いません。

このコードでは、`doSomething`関数から返される`data`の値（`"Hello from doSomething!"`）が`aaa`という引数に渡され、その結果がコンソールに出力されます。

名前の選択は、コードの可読性や意図を伝えるためのものなので、意味のある名前や一般的に理解しやすい名前を選ぶとよいです。
しかし、実際の動作には名前自体は影響しません。
スッキリわかるJava入門 実践編 第３版 まとめ - part2 -さまざまな種類のクラス

# はじめに
こんにちは　◤●ㅅ●◥ﾉ

今回は型安全から様々な種類のクラスについて学びました！
## 第２章　さまざまな種類のクラス
### 1.型安全
Javaでは変数の宣言をするとき必ず型を指定する
型を指定することでintなら整数、Stringなら文字列の情報のみ格納される
→格納するデータに制約をかける仕組みである

:thinking:なぜ制約をかける必要があるのか？色々な情報を入れられたら楽なのでは？
→呼び出しの際に間違える可能性がある、コンパイルの時にエラーが出ないため気づきにくい
　→変数に予期しない種類の情報が入ってしまうことを未然に防いでいる

型によって担保される安全性... __型安全__

 Javaには型安全のメリットをより享受するために
　「ジェネリクス」や「列挙型」という仕組みがある

### 2.ジェネリクス
ArrayListをはじめとするコレクションクラス
→ArrayList<String>のように＜＞で型を制限している
　→型安全のためにコレクションクラスは常に<~>をつけて利用する

:thinking:なぜコレクションくらすだけ<~>が使えるのか？
→ArrayListやHashMapは普通のクラスではなく __ジェネリクス__ という特別な仕組みを使って定義されている

ジェネリクスの確認方法
　APIリファレンスにおいても<~>という表記があるためそこで確認する

ジェネリクスはクラスだけでなくメソッドでも使うことができる
:pencil2: ジェネリクスのメソッド
```
アクセス修飾子　static<T> 戻り値　メソッド名(引数リスト)
{メソッドの処理内容}
```
### 3.列挙型
Javaでは指定した種類の値だけを入れることのできる列挙型を利用することができる

:pencil2: 列挙型の定義
```
アクセス修飾子　enum 列挙型名　{
　列挙子１, 列挙子2, 列挙子3, ...列挙子x, 
}
```
### 4.インナークラス
Javaではクラス宣言ブロックの中にさらにクラス宣言を書くことができる
→内部に宣言されたクラス... __インナークラス__　という

インナークラスは宣言される場所によって３種類に分類される
・メンバクラス
　宣言場所：クラスブロックの中、フィールドやメソッドの隣
・ローカルクラス
　宣言場所：メソッドブロックの中、他の文の隣
・匿名クラス
　宣言場所：文の中（式の一部、親クラス名を指定）

:star: ３種類のインナークラスに共通する特徴
・あるクラスの内部で宣言される
・外側クラスのメンバや変数に対して特別にアクセスできる

#### メンバクラス
　あるクラスのメンバとして定義するクラス

※メンバ...クラスに用意した変数やメソッドを総称してメンバと呼ぶ

通常のクラスとの大きな違い
・クラスブロックの中でメンバとして宣言する
・protextedやprivateといったアクセス修飾も利用可能である

また、staticがあるかどうかで利用法が変わる
:star: staticメンバクラスの特徴
・基本的に「外部クラス名、メンバクラス名」で利用する
・外部クラスのメンバにアクセスできるがstaticなものに限られる

:star: staticなしメンバクラスの特徴
・外部クラスのインスタンスがなければnewできない
・結びついている外部インスタンスの非staticメンバにもアクセスできない

#### ローカルクラス
メソッドブロックで宣言されるクラス定義

:star: ローカルクラスの特徴
・宣言したメソッド内でのみ有効で、他のクラスやメソッドからは利用できない
・finalとabstract以外の修飾は行えない
・外部クラスのメンバにはアクセス可能

#### 匿名クラス
通常のクラスや他のインナークラスと比較してもかなり異質な存在

:star: 匿名クラスの特異性
通常のクラスやメンバクラスは、classキーワードでまず定義を「宣言」し、
その後newで「利用」するが、匿名クラスは「宣言と利用」を同時に行う

:pencil2: 匿名クラスの宣言兼利用
```
new 匿名クラスの親クラス指定(){
 匿名クラスの内容(メンバ)定義
}
```

### 5.null安全性
:star: null安全とは
変数にnullが格納される余地があると、例外や不具合の原因になる可能性がある。
そのためプログラミング言語として「そもそもnullを格納できない仕組み」や
「nullが格納されている可能性を考慮したプログラムの記述が強制される仕組み」を備えることが望ましい

利用法
Optionalクラスをメソッドの戻り値の型として用いることで、null安全に考慮したプログラムを生成できる

## まとめ
型は変数に予期しない種類の情報が入ってしまうことを未然に防いでいる
このように型によって担保される安全性のことを型安全という
ArrayListをはじめとするコレクションクラスや型列挙、インナークラスを使うことで型安全のメリットを享受しやすくなる
インナークラスには３種類の分類に別れており、共通点はあるクラスの内部で宣言される、外側クラスのメンバや変数に対して特別にアクセスできることの２つである
docker compose内でのプライベートパッケージ取得

`Dockerfile`
```Dockerfile
RUN apk --no-cache add openssh-client \
    && mkdir -p -m 0700 ~/.ssh \
    && git config --add --global url."ssh://git@github.com".insteadOf "https://github.com" \
    && ssh-keyscan github.com >> ~/.ssh/known_hosts

# e.g. RUN --mount=type=ssh go build
```

`compose.yaml`
```yaml
services:
  app:
    build:
      ssh:
        - default
```
troccoでメモリオーバーになった場合の対処

# はじめに
troccoを使ってデータ転送を行う際、発生したエラーの解決法がパッとは出てこなかったので、誰かの役に立ったら嬉しいなと思い書いておきます。
あと、サポート担当の方が丁寧に教えてくれたので、ググって出てくるようになったら恩返しになるかなと。あとtroccoのサポート良いよ。ってことも付け加えておきます。

## 環境情報

* Source
    * MongoDB
* Dest
    * BigQuery


# 起こったことと対処方法

## 概要

MongoDBからBQにデータを転送するジョブを設定。
また、日次でデータが更新されるようスケジュールも設定。

公式では `incremental_field` はシーケンシャルなユニークなキーを使うことを推奨していますが、`_id` はこれに該当しないため代替として更新日時を利用するよう設定しました。


## 発生したエラー

上記のジョブを設定後、実行してみたところ以下のエラーが発生しました。

```
Query failed with error code 292 and error message 'Executor error during find command :: caused by :: Sort exceeded memory limit of 104857600 bytes, but did not opt in to external sorting.' on server [server address]
```

スクショ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140133/5cfa7d35-62cf-a4fd-642a-860cec2004c8.png)



## サポートにヘルプを依頼

色々と試行錯誤しましたが解決の糸口が見つからなかったので、サポートに確認したところ以下の回答でした。

> 初回の転送データが大きいことが原因となりますので、初回のみ転送するデータをクエリで分割していただけますと幸いです。
差分転送に切り替える際は、転送済みのMAX(id)やMAX(date)の値を最後に転送されたレコードに入力いただければ積み上げで転送されていきます。
（以下略）

なるほど。そういうことね。
じゃあ転送設定のクエリでフィルタ設定をしよう。ということで以下を設定してみました。

```
{ "create_datetime": {"$lte": ISODate("2022-09-01T00:00:00.000Z")} }
```

しかし、設定後に「接続を確認」を行ったところ以下のエラーが表示されました。

```
認証時にエラーが発生しました。設定をご確認ください。
invalid format
```

うーん。
実データのタイムスタンプのフォーマットは間違っていない。
MongoDB compassで構文を確認してみましたが、それも問題は無い。

再度サポートにヘルプを依頼したところ、

> 拡張JSON形式であればクエリできることを確認いたしました。

ということで、最終的に以下を設定することで対応できました。

```
{"create_datetime": {"$lte":{"$date":"2022-09-01T00:00:00.000Z"}}}
```


# まとめ

1. 以下のエラーが出たら転送量を制限して初期データを投入しましょう
    ```
    Query failed with error code 292 and error message 'Executor error during find command :: caused by :: Sort exceeded memory limit of 104857600 bytes, but did not opt in to external sorting.' on server [server address]
    ```
1. クエリでフィルタする場合は拡張JSON形式で設定しましょう
1. troccoサポートは丁寧で素晴らしい
ペッパー付きハッシュ値の場合のSQLインジェクション認証回避の練習問題の解答

https://qiita.com/ockeghem/items/0f3b09a0f413bdd39bd5

今回はこちらの記事を考えてみました。

> ソースコードやテーブル定義は見てもよいことにしますが、「見なくても攻撃できる」方が良い解答とします。

ということでしたので、お言葉に甘えて、テーブル名および各カラム、adminの`userid`は`admin`と判明している前提での挑戦です。


今回はペッパー付きとのことで、自前で用意したハッシュ値を送り付けて認証させる方法は難しそうですが、利用者がユーザー登録できるということですので、まず攻撃用のダミーアカウントを登録しました。

![02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618708/bfbc70bd-fb40-70a3-2318-12f2ae07ca8c.jpeg)

```txt:
userid : test
password: test
email: test@example.com
```

その後、

<details><summary>フォーム入力値</summary><div>

UserID　`' union select (select id from users where userid = 'admin'), 'admin',(select password from users where userid = 'test'), (select email from users where userid = 'admin'); --`

Password `test`

![03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618708/f22e2484-34d4-ee10-424a-81536bc10d24.jpeg)

</div></details>

でとりあえず行けたようです。

![04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618708/d029271c-cb6d-677d-050b-01b21ba03aaf.jpeg)

![05.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618708/592c844d-0413-ef8c-cd33-85c101d4c6a3.jpeg)
マネジメントの主な仕事内容


マネージメントとして大切な点について纏めてました。
キャリアアップに繋がることができればと存じます。

# ①目標管理マネジメント
部署の掲げた目標を達成するために、部下を管理していくこと。

    ・目標の具体的なゴールを決定し、繰り返し部下に伝達する
    ・目標をチームで共有する。
    ・個人目標とチーム目標とをすり合わせる
    その際、「お互い納得できる定量目標や評価基準を設定する」「期初、部下に評価基準を伝達する」なども必要となります。

# ②業務進捗管理マネジメント
目標の達成に向けて部下の業務をサポートすること

    ・各プロジェクトに応じて、管理体制を月別・週別・日別で設定する
    ・業務の進捗管理を行う
    ・蓄積した事例をデータ化し、分析する、ノウホウを蓄積することで、次のプロジェクトに役に立つ

    ・順調の場合……………………より高い成果へ導くように指導
    ・不調の場合……………………原因を分析し、必要に応じたサポートし、同じミスは振替さないようにサポート

# ③チームマネジメント（組織をつくる）
必要とされる活動、意志決定、関係を分析し、仕事を分類する。
それらの仕事を行うべきメンバーの役割を分担して、
目標達成に向けチームをけん引していくこと

    ・個々のメンバーのモチベーションを確認する
    ・個々のメンバーの経験やスキルを踏まえ、役割を振り分ける
    ・役割ごとに主担当者を決める
    ・チームで共通認識を作り、協働の雰囲気を作る

# ④自らを含めて人材を育成マネジメント
部下が自身の能力を最大限発揮できるように個々を成長させること。

    ・部下の個性や適正を見極め、強みを引き出す
    ・部下の仕事への真摯さを強化する。
    ・部下の成長目標を定め、より上に到達できるよう指導する

# ④評価測定する
組織全体の成果に焦点を合わせ、かつ自らの仕事に焦点を合わせた尺度、
メンバーを助けになる尺度を設定する。

    ・仕事ぶりを分析し、評価し、解釈すること
    ・メンバーに納得できる評価をなされること
    ・評価測定の意味と結果を部下と上司に伝えること
※メンバーにあった評価をなされる場合、組織（会社）を辞める動機となり、人材の流出もなるのではないでしょうか

# ⑥メンタルヘルスのマネジメント
メンタルヘルスマネジメントとは、部下の精神面における健康をケアすること。

    ・メンバーが気軽になんでも気軽に相談できる雰囲気の環境を作る
    ・メンバーから相談があった場合、必要な協力を惜しまず親身に対応する
非同期処理と同期処理の違い

非同期処理と同期処理は、プログラムの実行の仕方や順序における2つの主要なアプローチです。
それぞれの特性を以下に説明します。

## 同期処理 (Synchronous)
1. **一つずつ順番に実行**: 同期処理では、コードは上から下へと一つずつ、順番に実行されます。

2. **待機**: もし途中の操作が時間がかかるもの（例えば、大量のデータを処理する操作）であった場合、その操作が完了するまで次の操作は待機されます。

3. **ブロック**: 上記の待機のため、時間がかかる操作中はアプリケーション全体が「ブロック」され、他の操作を受け付けないことがあります。

## 非同期処理 (Asynchronous)
1. **同時に複数の操作**: 非同期処理では、一つの操作が完了を待たずに次の操作が始まることができます。

2. **コールバックやPromise**: 非同期の操作が完了したら、コールバック関数を実行したり、Promiseが解決または拒否されることで、その結果を取り扱うことが一般的です。

3. **非ブロッキング**: 非同期処理はアプリケーションを「ブロック」しないので、例えばネットワークリクエストを待っている間もユーザーインターフェースは反応し続けることができます。

## 例

**同期的な例**:
```javascript
const result = database.fetchData();
console.log(result);
console.log("Finished");
```
上記の場合、`fetchData`の処理が終わるまで、次の`console.log`の実行が待たれるため、データ取得に時間がかかると"Finished"の出力も遅れます。

**非同期的な例**:
```javascript
database.fetchDataAsync((result) => {
    console.log(result);
});
console.log("Finished");
```
上記の場合、非同期の`fetchDataAsync`が即座に返し、"Finished"が先に出力される可能性があります。
データの取得が完了したら、コールバック関数が実行されて結果が出力されます。


## 結論
**同期処理**は順番に一つずつ処理が行われ、一つの処理が終わるまで次の処理は待たされます。
一方、**非同期処理**では、一つの処理が終わるのを待たずに次の処理が進行し、結果や完了の通知は後からコールバックやPromiseを使って取り扱われます。

その他わかりやすかった記事：[非同期処理とは何か、何が嬉しいの？](https://qiita.com/yunity29/items/7ccc84d47e139340ecbc)
Pythonをインストールしているがターミナルで command not foundと表示された時

## はじめに
自分のメモ書きで許してください。

## Pythonのインストール手順
私は`brew`を使って以下のようにPythonをインストールしました。
```
brew install python
```

Pythonを実行します。
```
python
```
すると`command not found: python`と表示されてしまいました。
![Screenshot 2023-09-20 at 14.00.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318755/04c378b4-6cd5-8293-0a18-339941f3f21d.png)

## 解決方法
```
python3
```
`python3`とコマンドを実行することで解決できました。

![Screenshot 2023-09-20 at 14.04.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318755/32eefc00-22b4-bfbd-6b67-200f0a03524c.png)

過去２回も同じミスにハマってしまったので、ブログにしました。





## 追記：実行コマンドを終了する
```
exit()
```
`exit()`を使うことでPythonの実行を終了できます。
Vue3 + Viteを仮想OS上でDockerを利用して作成

## はじめに
DockerでViteとVue3の開発環境を立ち上げる作業を行った。映し出すまでに少し手間どってしまったので、理解を深めるためにもメモを残す。

## ゴール
オンプレサーバー内の仮想OSでDockerを導入していてdocker compose v2なども導入済みです。
今回のゴールはAmazonLinux2023のイメージを利用してVite+Vue3の開発環境を`http://xxx.xxx.xxx.xxx:5173`でアクセスできる状態にすることです。


## 参考：
https://zenn.dev/iloveomelette/scraps/da45d505ffaefc
https://qiita.com/generonishimura/items/88742085294bd0b234a6

## 作業手順
1. 開発用ディレクトリを作成
2. `Dockerfile`と`compose.yml`を作成
```Dockerfile
FROM amazonlinux:2023

# dnfのアップデート
RUN dnf update -y

# Node.jsのインストール
RUN curl -sL https://rpm.nodesource.com/setup_20.x | bash - && \
    dnf install -y nodejs

# Viteのインストール
RUN npm install -g vite

# コンテナ内の作業ディレクトリを作成
WORKDIR /app

# ポート番号5173でコンテナを公開
EXPOSE 5173
```

```compose.yml
services:
  frontend:  # サービス名
    build:  # Dockerfileの設定
      context: .  # Dockerfileを置いているディレクトリ
      dockerfile: Dockerfile  # Dockerfileのファイル名
    working_dir: /app  # 作業ディレクトリを指定
    volumes:
      - ./:/app:cached
    tty: true  # コンテナを正常終了するのを防ぐ
    ports:
      - '5173:5173'  # 公開用のポート指定。ホスト側:コンテナ側
    command: npm run dev  # viteの実行コマンド
volumes:  # 名前付きボリュームの設定
  node_modules:
```

3.ホストマシン（仮想OS）でビルド
```
docker compose build
```

4.Dockerコンテナ内でViteを利用してVueアプリを作成（Vueを指定し、プロジェクト名は今回は「vue-vite-sample」とした）
```
docker-compose run frontend npm run vite
```

5.Dockerfileとcompose.ymlに追記する
```Dockerfile
FROM amazonlinux:2023

# dnfのアップデート
RUN dnf update -y

# Node.jsのインストール
RUN curl -sL https://rpm.nodesource.com/setup_20.x | bash - && \
    dnf install -y nodejs

# Viteのインストール
RUN npm install -g vite

# コンテナ内の作業ディレクトリを作成
WORKDIR /app

# 追記
# プロジェクトのコピー
COPY vue-vite-sample/ ./

# ポート番号5173でコンテナを公開
EXPOSE 5173
```

```compose.yml
services:
  frontend:
    build:
      context: .
      dockerfile: Dockerfile
    working_dir: /app
    volumes:
      - ./vue-vite-sample:/app:cached
      - node_modules:/app/node_modules
    tty: true
    ports:
      - '5173:5173'
    command: npm run dev
volumes:
  node_modules:
```

6.vite.config.tsを書き換え（ホストではなく外部公開するため）
```typescript
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  server: {
    // 外部公開
    host: '0.0.0.0',
    // 立ち上げる際のポートを変更できます。
    port: 5173
  }
})
```

7.再度ビルドする
```
docker compose build --no-cache
```

8.コンテナの立ち上げ
```
docker compose up
```

9.IPとポートを指定してアクセス
```
http://xxx.xxx.xxx.xxx:5173/
```

![rapture_20230920124712.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/781232/d6e20a2f-4fb1-0ae1-4fec-a4c7614bc03e.jpeg)
Markdown記法について

# コードの挿入
**Code blocks - コードブロック**
```js:qiita.js
const session = require('express-session')
```

```diff_javascript
- const session = require('express-session')
+ const express = require('express')
```

**Code spans - コードスパン**
```js:qiita.js
`console.log('こんにちは');`と書くことでインライン表示
```
`console.log('こんにちは');`と書くことでインライン表示

**コードスパン内でバッククオートを使う**
開始・終了のバッククオートをn+1個で囲む。
`` `バッククオート` `` や ``` ``2連続バッククオート`` ```

**コードスパンの中身がCSSの <color> 型**
 `#ffce90`
`rgb(403,352,0)`
`rgba(0,255,893,0.4)`

# Format Text - テキストの装飾
**Headings - 見出し**
# H1タグ
## H2タグ
### H3タグ

**Emphasis / Strong Emphasis - 強調・強勢**
もしかして君、*italic type* かい？
いいえ、**太字**です。

**Strikethrough - 打ち消し線**
 ~~本当最高です！~~

**Details - 折りたたみ**
<details><summary>例 1</summary>
</details>

**Note - 補足説明**

:::note 
インフォメーション
infoは省略可能です。
:::

:::note warn
注意
ここでは、 定数を使ってください。
:::

:::note alert
必ず確認してください
紹介しているバージョンは古いバージョンになります。
:::

# Lists - リスト
**Bullet List - 順序なしリスト**
- あ
- り
- が
- と
- う

**Ordered List - 番号付きリスト**
1.　リスト
　1.　トースト
1\.　トイレ
エスケープ

**Description List - 説明リスト**
<dl>
  <dt>リンゴ</dt>
  <dd>赤いフルーツ</dd>
  <dt>オレンジ</dt>
  <dd>橙色のフルーツ</dd>
</dl>

<dl>
  <dt>リンゴ</dt>
  <dd> とても<strong>赤い</strong>フルーツ </dd>
</dl>

**Checkbox - チェックボックス**
- [ ] task1
- [x] task2
- [x] task3

# Blockquotes - 引用

> 引用
> > これはネストされた引用です。
> > > さらにネストされた引用

# Horizontal rules - 水平線

* * *
***
*****
- - -
---------------------------------------

# Links - リンク

[Yahoo](https://www.yahoo.co.jp/ "Yahoo Home")

[Yahoo](https://www.yahoo.co.jp/)


[このサイト][link-1] と [このサイト][link-1]のリンクは同じになります。
[link-1] という書き方もできます。

[link-1]: http://qiita.com/

# Images - 画像埋め込み

![Qiita](https://qiita-image-store.s3.amazonaws.com/0/45617/015bd058-7ea0-e6a5-b9cb-36a4fb38e59c.png "Qiita")

<img width="30" src="https://qiita-image-store.s3.amazonaws.com/0/45617/015bd058-7ea0-e6a5-b9cb-36a4fb38e59c.png">

# テーブル

|1   |2   |3   |4   |
|:-: |:-: |:-: |:-: |
|1   |3   |4   |5   |
|2   |4   |5   |6   |
|3   |5   |6   |7   |
|4   |6   |7   |8   |
|5   |7   |8   |9   |

| Left align | Right align | Center align |
|:-----------|------------:|:------------:|
|　　砂糖       　| 塩        　　　　　| みりん         |
| column     | column      | column       |

| 1 | 2 |
|:-:|:-:|
|ありがとう   |\|ございます\|   |

**HTMLで入力する場合**

<table>
  <caption>HTMLを使った記法</caption>
  <thead>
    <tr>
      <th>名前</th> <th>説明</th>
    </tr>
  </thead>
  <tr>
    <td> table </td> <td>テーブル</td>
  </tr>
  <tr>
    <td> caption </td> <td>キャプション</td>
  </tr>
</table>

# 数式の挿入

$$ e^{i x} = \cos{x} + i \sin{x} $$
x^3 + y^5 = 5 をインライン表示すると $x^3 + y^5 = 5$ になります。
$a = \\{1, 2, 3\\}$

# 目次(TOC)の自動挿入

記事内の見出しを元に自動で挿入

# 脚注
これについては諸説あります。[^1]
[^1]:実は病死説もある。

# 絵文字
💕ハート

# リンクカード

http://www.emoji-cheat-sheet.com/

# ダイアグラム
**PlantUMLを使う**

```plantuml
participant Last order 30
participant Middle order 20
participant First order 10
```

**Mermaidを使う**
```mermaid
sequenceDiagram
    participant A as Alice
    participant J as John
    A->>J: Hello John, how are you?
    J->>A: Great!
```

**複数のノードをまとめて表現する**

```mermaid
flowchart TB
    A & B--> C & D
```

# コンテンツの埋め込み

- https://codesandbox.io/
- https://www.figma.com/ja/

# その他
\**エスケープ**
\をMarkdownの前に挿入する
JMESPathのcontainsを使ってincludesとかin_array的なことをする

:warning: この文章はGPT-4により生成されています

JMESPathは、JSONドキュメントを照会するための言語である。この言語を用いれば、大きなJSONデータから特定の情報を取り出したり、データの変換を行ったりすることができる。今回のテーマは、JMESPathの `contains` 関数を活用して、JSONの配列に特定の値が含まれているかどうかの判定方法である。

## containsの基本的な使用方法

JMESPathの `contains` は、ある配列に指定した値が含まれているかどうかを調べる関数である。基本的な使用方法は以下の通り。

```json
contains([検索対象の配列], 探す値)
```

この関数は、検索対象の配列に探す値が含まれている場合に `true` を、含まれていない場合に `false`を返す。

## containsの応用的な使用方法

JMESPathの `contains` 関数は、第1引数にリテラル配列を指定し、第2引数に変数を指定することで、その変数がリテラル配列内のいずれかの要素と一致するかどうかを確認することができる。例として、以下のJSONデータを考える。

```json
{ "targetNames": ["Alice", "Bob", "Charlie", "David"] }
```

このデータに対して `targetNames` に含まれる全ての名前が `["Alice", "Bob", "Charlie"]` という配列に含まれているかどうかを確認する照会を行う。

```json
map(&contains(["Alice", "Bob", "Charlie"], @), targetNames)
```

この照会は `targetNames` 内の各名前が `["Alice", "Bob", "Charlie"]` に含まれているかどうかを確認し、その結果の配列を返す。結果は `[true, true, true, false]` となる。

## AWS CLIでのcontains関数の使用

AWS CLIの--queryオプションを使用して、特定のJSONデータの要素を絞り込む際に、JMESPathの `contains` 関数は非常に有効である。例えば、AWS Step Functionsの実行履歴から特定のIDのイベントだけを取得したい場面を考える。以下のコマンドを実行することで、IDが1, 3, 5, 7, 9のいずれかであるイベントだけを絞り込んで取得することができる。

```bash
aws stepfunctions get-execution-history \
--execution-arn arn:aws:states:ap-northeast-1:000000000000:execution:xxx:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx \
--query 'events[?contains([`1`,`3`,`5`,`7`,`9`],id)]'
```

このように、JMESPathの `contains` 関数を活用することで、JSONデータの照会や変換、そしてAWS CLIでのデータの絞り込みが非常に効率的に行えるのである。
関数とオブジェクトとメソッドとプロパティの違い

それぞれの概念を簡潔に説明します。


## **関数 (Function)**:
   - 一連の手続きや動作を実行するためのコードのまとまりです。
   - 一度定義すれば、何度でも再利用することができます。
   - 引数を取ることができ、また戻り値を返すこともできます。

     例：
     ```javascript
     function add(a, b) {
       return a + b;
     }
     ```

## **オブジェクト (Object)**:
   - キーと値のペアの集合体です。この「キー」は「プロパティ」としても知られています。
   - オブジェクトはデータと機能（メソッド）を1つにまとめることができます。

     例：
     ```javascript
     const person = {
       name: 'Alice',    // プロパティ
       age: 30,          // プロパティ
       greet: function() {   // メソッド
         console.log('Hello!');
       }
     };
     ```

## **メソッド (Method)**:
   - オブジェクトの中に定義される関数です。
   - 通常、オブジェクトのプロパティや他のメソッドにアクセスするために使います。

     例（上記のオブジェクトからの抜粋）：
     ```javascript
     greet: function() {
       console.log('Hello!');
     }
     ```

## **プロパティ (Property)**:
   - オブジェクトの中に保存されるデータのことを指します。
   - 名前（またはキー）と値のペアで構成されます。

     例（上記のオブジェクトからの抜粋）：
     ```javascript
     name: 'Alice',
     age: 30
     ```

## 結論
- **関数**は何らかの動作を表すコードのまとまりです。
- **オブジェクト**は関連するデータと機能をまとめたものです。
- **メソッド**はオブジェクトの中の関数で、オブジェクト内のデータや機能にアクセスするために使います。
- **プロパティ**はオブジェクトの中のデータを指します。
【AWS】AWS SAPの勉強メモ

# 始めに
AWS SAPの勉強を始めましたが、必要な知識量が膨大で
絶望。。

そこで最近学んだ内容をメモしておくだけになりますが
SAP勉強中の方にほんの少し、参考になれば程度の記事です。
※SAAレベルの内容も含みます

# SAP学習中に学んだサービス
## ▪️AWS RAM
アカウント間でリソースを共有するためのサービス

## ▪️Direct Connect Gateway
複数のリージョンのVPCに接続できる


## ▪️パブリックVIF
オンプレのデータセンターがAWSパブリックサービスに
アクセスできる

## ▪️AWS Firewall Manager
複数アカウントやOUのWAFルールを一元管理できる
Organizationsのアカウント間でWAFルールを一元管理する。

## ▪️AWS DMS(database migration service)
DBをAWSへ迅速かつ安全に移行するのに役立つ
移行中もDBは完全に利用可能状態が保たれ、
アプリのダウンタイムは最小限になる。

異なるプラットフォームでも同じでも、移行可能で
低レイテンシーかつ継続的にデータをレプリケートできる。

## ▪️AWS Budgets
視覚化して予算と通知を定義する機能をもつ

コストや使用量が予算量を超える、または超えると予測した場合
アラートを出すカスタム予算を設定可能。

## ▪️AWS Fargate
・コスト効率は良くない

## ▪️ファイルゲートウェイ
・Lambda及びRecognitionから直接アクセスできるファイルをS3に保存し、
動画からメタデータを分類or識別し、検索のためにMAMソリューションに保存可能

・NFSなどのプロトコルを用いて、S3オブジェクトの取得や保存が可能
・S3で直接アクセス可能
・ローカルキャッシュを利用するため、高速なデータアクセスが可能

## ▪️AWS Config
・リソース設定の変更を追跡や記録をし、AWSのイベントリソースを作成する
→これによりエンジニアのセキュリティ設定の変更が可能

・EC2セキュリティグループに対する変更を検出する
・結果はSNSトピックへ送信し、設定変更がリアルタイムで通知される

## ▪️AWS Global Accelerator
・ALBのエンドポイントとして設定することで、客にElastic IPを提供できる
・グローバルアクセスと高可用性を提供する
・ALB自体は直接ElasticIPアドレスを割り当てることができない
・ALB背後のEC2とのアクセスを円滑にできるよう、静的なIPアドレスを提供できる

## ▪️S3マルチリージョンアクセスポイント
・S3クロスリージョンレプリケーション＋マルチリージョンアクセスポイントで
アプリのデプロイを２つのリージョンに拡張可能
・運用のオーバヘッドも少
・データの整合性も保てる

## ▪️RDSリードレプリカ
読み取り負荷を分散させる

## ▪️AD Connecter
既存オンプレのActive DirectoryをAWSに接続するのに役立つ
・負荷分散
・シングルサインオン(SSO)
・双方向の信頼関係が必要で、AWSにインストールする

## ▪️AWS Fargate
サーバーやコンテナの管理する手間をなくせる、サーバーレス実行環境。
運用管理の負担を減らす目的で使われることが多い。
mojxml2geojsonのインストール(Windows版)

# mojxml2geojson

デジタル庁で公開している `法務省登記所備付地図データ（地図XML）をGeoJSONに変換するコンバータ (mojxml2geojson)` をWindowsにインストールする手順を紹介します。
(自分用メモ)

https://github.com/digital-go-jp/mojxml2geojson

# Python3のインストール

まずはPython3 の最新版をインストールします。

https://www.python.org/downloads/

インストールが終わったら、確認してみましょう。

```
> py --version
Python 3.11.5
> py -m pip --version
pip 23.2.1 from C:\Program Files\Python311\Lib\site-packages\pip (python 3.11)
```

# Anaconda のインストール

condaコマンドを使うので、Anacondaのインストールが必要です。

https://www.anaconda.com/download

Anaconda をインストールしたあと、PowerShellを起動して、以下を実行
```
C:\Users\(username)\anaconda3\condabin\conda.bat init powershell
```

コマンドプロンプトの場合は以下のコマンドを実行
```
C:\ProgramData\Anaconda3\Scripts\conda init cmd.exe
```

condaコマンドを反映させるため、一度、PowerShellまたはコマンドプロンプトを閉じる

PowerShellまたはコマンドプロンプト を開き、以下のコマンドを実行。condaに関する情報が表示されることを確認。

```
>conda info

     active environment : base
    active env location : C:\Users\(username)\anaconda3
            shell level : 1
       user config file : C:\Users\(username)\.condarc
 populated config files :
          conda version : 23.7.4
    conda-build version : 3.26.0
         python version : 3.11.4.final.0
       virtual packages : __archspec=1=x86_64
                          __win=0=0
...
```

# gdal Windows のインストール

下記コマンドを実行（で良いはず）
```
conda install -c conda-forge gdal
```

インストール後に、環境変数を設定します。

変数名| 値
------|----
PATH | C:\Program Files\GDAL を追加
GDAL_DATA| C:\Program Files\GDAL
GDAL_DRIVER_PATH | C:\Program Files\GDAL\gdalplugins
USE_PATH_FOR_GDAL_PYTHON | YES

PowerShell / コマンドプロンプトの場合は、開き直します。

# mojxml2geojson のインストール

下記コマンドを実行
```
pip install git+https://github.com/digital-go-jp/mojxml2geojson.git
```

`mojxml2geojson.exe` があるはず。

```
> mojxml2geojson.exe
usage: mojxml2geojson [-h] [-e] FILE_PATH
mojxml2geojson: error: the following arguments are required: FILE_PATH
```

# 使う

G空間情報センターからデータをダウンロード。


Zipファイルを展開(x2)

```
> mojxml2geojson.exe .\01101-4300-3.xml
```

`01101-4300-3.geojson` ができているはず。
跨文化教育的力量：如何利用國際學校經驗成功赴美留學

"近年來，隨著台灣國際化的發展，越來越多的家庭開始考慮送子女到國際學校就讀。出國留學已經不再是一個遙不可及的夢想，而是讓孩子接觸國際視野、拓展未來發展機會的重要途徑之一。其中，美國的國際學校特別受到台灣家庭的青睞，因為美國教育體系的優勢和[美國簽證](https://www.apexcharity.org/news/3/94)政策的相對寬鬆。

首先，[出國留學](https://www.apexcharity.org/news/3/83)對孩子的成長和發展有著重要的影響。在國際學校，孩子能夠接觸到不同國籍的同學，並且在多元文化的環境下學習和交流。這不僅能夠提升孩子的語言能力，還能夠培養他們的國際視野和跨文化交流的能力。同時，[國際學校](https://www.apexcharity.org/news/3/82)的教育模式更加注重培養學生的創造力、批判性思維和團隊合作能力，這些都是未來職場所需要的重要素養。

而在選擇國際學校時，考生通常需要通過[SAT](https://www.apexcharity.org/news/3/84)考試以證明自己的學術能力。SAT是美國大學招生的重要指標之一，也是國際學生進入美國大學的必備考試。因此，在準備SAT考試時，學生和家長應該重視專業的培訓和指導。許多國際學校提供SAT考試的相關課程，幫助學生掌握考試的技巧和知識點，提高他們的考試成績。

另外，美國簽證是出國留學的必要程序之一。台灣學生通常需要申請F-1學生簽證才能夠合法在美國就學。申請簽證需要準備相關的文件和證明材料，包括學校錄取通知書、財力證明以及簽證申請表等。此外，學生還需要通過面試，向美國領事館證明自己的學術和財力狀況，以確保能夠獲得簽證。

總結來說，出國留學是一個讓孩子接觸國際視野、拓展未來發展機會的重要途徑。在選擇國際學校時，家長應該考慮教育質量、師資水平以及學校的國際認證等因素。同時，學生在準備SAT考試和申請美國簽證時，應該尋求專業的指導和幫助，以確保自己能夠達到最好的成績和順利申請到簽證。讓我們一起為孩子的未來，提供最好的教育機會吧！"
HTMLタグ内で使える「tabindex」属性について

とあるサイトを閲覧していた際に、使ったことのない「**tabindex**」属性を見つけたのでまとめてみました。

tabindexとは？
-

まず、[mdn web docs](https://developer.mozilla.org/ja/docs/Web/HTML/Global_attributes/tabindex "mdn web docs")では以下のように説明されています。
> tabindex グローバル属性は、開発者が HTML要素をフォーカス可能にし、（ふつうは名前の由来である Tab キーによる）順番にフォーカスすることを許可または防止し、順番にフォーカスするための相対順序を決定することができるようにします。
>
> HTML 要素がレンダリングされ、その tabindex 属性が有効な整数値である場合、その要素は JavaScript で（focus() メソッドを呼び出すことで）フォーカスしたり、マウスクリックで視覚的にフォーカスしたりすることができます。

どういうことか、ソースコードを使って解説します。
``` :解説用ソースコード
<div>
    <p>inputタグ1：</p><input type="text">
</div>
<div>
    <p>inputタグ2：</p><input type="checkbox">
</div>
<div>
    <p>inputタグ3：</p><input type="button" value="ボタン">
</div>
```
そもそも、「input」や「a」などの一部のタグは上記の属性を設定しなくてもtabキーでフォーカスすることができます。（下記gifの黒い線に囲われた部分がフォーカスされている部分です。）
![tab選択.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3489679/9d15162d-8947-7d14-a7cf-4f469d9660f8.gif)
でも、「div」や「p」で囲っている部分についてはフォーカスはされていませんね。
こういったタグにもtabフォーカスができるようになったり、逆にフォーカスさせないようにする、ということができるようですね。

フォーカスさせてみよう
-
さっそく「p」タグにtabフォーカスをさせてみましょう。
下記のようにtabindexを入れてあげると…
```
<p tabindex="0">inputタグ1：</p>
```
![20230920120845.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3489679/e754f7e4-d6c5-1cd0-9012-0da0ad1ff9f1.gif)

「inputタグ1：」もフォーカスされるようになりましたね。
「tabindex="1"」「tabindex="2"」「tabindex="3"」などと指定してあげれば、この順番通りにtab選択できるようになります。

フォーカスを防止してみよう
-
今度は「inputタグ2：」にあるチェックボックスがフォーカスされないようにしてみましょう。
```
<input type="checkbox" tabindex="-1">
```
![20230920125010.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3489679/1b299576-f8b7-5989-715b-4fad55056e02.gif)
負の数を付けてあげることで、このようにフォーカス防止ができます。

追記：注意事項
-
@juner(jun maeda)さんからコメントをいただきましたので、こちらにも追記します。
>ただし、
>>警告: tabindex の値として、0 と -1 のみを使用することをお勧めします。tabindex の値を 0 より大きくしたり、フォーカス可能な HTML 要素の順序を変更できる CSS プロパティ（フレックスアイテムの並べ替え）を使用したりしないようにしましょう。これは、キーボードによるナビゲーションや支援技術を使用している人にとって、ページのコンテンツを操作することが難しくなります。代わりに、論理的な順序で要素を記述してください。
>とあるので基本的には tabindex は 0(初期値) か-1(非フォーカス) の使用に限定するべきですね。

まとめ
-
:::note info
・tabindexはtabフォーカスを新しくつける事ができる
・順番の指定も行えるが、値は0 か -1 のみに限定する
・フォーカスを防止することもできる
:::

tabindexを指定しておくことでスムーズなページ移動ができるようになります。
webデザインは「上から下」「左から右」といった導線がほとんどですので、このルールに則っているのであれば付ける事によって逆に混乱のもとになります。乱用しないようにしましょう。
zipしたのになぜか中身が空になってしまう

## 結論

`-r`をつけましょう。

### 書式

```bash
# 書式
$ zip -r <圧縮後のzipファイル名> <圧縮するディレクトリのパス>
```

### 例1：/home/sigma/workを圧縮

```bash
$ zip -r sample.zip /home/sigma/work/
```

### 例2：カレントディレクトリ以下を全て圧縮

```bash
$ zip -r sample.zip *
```

## 解説

`r`オプションは、`<圧縮するディレクトリのパス>`で指定したディレクトリに含まれるディレクトリやファイルを**まとめて圧縮するためのオプション**。

つまり、**`r`オプションがなければディレクトリの中身は圧縮されない**ことになってしまう。

実質、`zip`コマンドを使うときは`r`オプションは必須。

## 感想

圧縮にはzipコマンドが使えることや引数の順番は覚えていたが、`r`オプションについては忘れていたので、何度`zip`しても空になってしまい焦った。

## 参考

- 三宅英明・大角祐介『新しいLinuxの教科書[初版]』（SBクリエィティブ株式会社、2015年）
NestJSを使用してMongoDB Atlasに接続する方法

## 前提

この記事では、NestJSをバックエンドに使用してMongoDB Atlasに接続する方法を解説します。MongoDB AtlasはMongoDB Inc.によって提供されるクラウドベースのデータベースサービスです。このサービスを使用すると、簡単かつ迅速にMongoDBデータベースをセットアップし、管理できます。

## 実装

- MongoDB AtlasのエンドポイントはmongodbConfigのように設定します。MongoDB AtlasのエンドポイントはMongoDB Atlasの任意のプロジェクトを選択し「DEPLOYMENT」「Database」から、任意のクラスターの「Connect」ボタンをクリックし、Drivers経由で接続すると表示・取得できますが、実際に使用する際はデータベース名まで指定する必要があります。以下の環境変数を設定ファイル（例：.env）やECSタスク定義などを使用して設定します。
    - MONGO_USER: MongoDBのユーザー
    - MONGO_PASSWORD: MongoDBのパスワード
    - MONGO_HOST: MongoDBのホスト
    - MONGO_DATABASE: MongoDBのデータベース名

    ```mongodb.config.ts
    const mongodbConfig = process.env.NODE_ENV === 'production'
      ? `mongodb+srv://${process.env.MONGO_USER}:${process.env.MONGO_PASSWORD}@${process.env.MONGO_HOST}${process.env.MONGO_DATABASE}?authMechanism=DEFAULT&authSource=admin`
      : `mongodb://${process.env.MONGO_USER}:${process.env.MONGO_PASSWORD}@${process.env.MONGO_HOST}:${process.env.MONGO_PORT}/${process.env.MONGO_DATABASE}?authMechanism=DEFAULT&authSource=admin`;

    export default mongodbConfig;
    ```

- ConfigModule: 環境変数をアプリケーション全体で利用できるようにするモジュールです。forRootメソッドを使用して、環境変数の設定を行います。
- MongooseModule: NestJSでMongoDBとの接続を簡単に行うためのモジュールです。forRootメソッドを使用して、MongoDBへの接続設定を行います。

    ```app.module.ts
    import { Module } from '@nestjs/common';
    import { ConfigModule } from '@nestjs/config';
    import { MongooseModule } from '@nestjs/mongoose';
    import mongodbConfig from '@/config/mongodb.config';
    
    @Module({
      imports: [
        ConfigModule.forRoot({
          envFilePath: ['.env'],
          isGlobal: true,
        }),
        MongooseModule.forRoot(mongodbConfig),
      ],
    })
    export class AppModule {}
    ```

自らの備忘録のために投稿してますが、なにかお役に立てましたら幸いです！:clap:
また、なにか間違ってましたらご指摘いただけますと幸いです！:pray:
【メモ】JS・TSにおける定数オブジェクトの設定について

## 下記の方法で、下記が実現できる
- オブジェクト自体の再代入が防げる
- オブジェクトのプロパティとその値が不変になる

```ts
export const SAMPLE_OBJECT = Object.freeze({
    NOT_SET: "未設定",
    AAA: "aaa",
} as const)
```

## as const
提供元：TypeScript
作動タイミング：コンパイル時に作動

## Object.freeze()
提供元：JavaScript
作動タイミング：ランタイム時に作動
Webサイト内の特定のHTML部品に含まれる文字数を算出する

個人的な需要があったので書きました。

## 1.事前準備

```terminal
brew install node
```

```terminal
npm install node-fetch jsdom
```

## 2.コード

```count_characters.mjs
import fetch from 'node-fetch';
import { JSDOM } from 'jsdom';

async function countCharacters(url) {
  try {
    const response = await fetch(url);
    if (!response.ok) {
      throw new Error(`Failed to fetch URL: ${url}`);
    }

    const html = await response.text();

    const dom = new JSDOM(html);
    // 抽出したいDOMを指定する
    const element = dom.window.document.querySelector('#example');

    if (element) {
      const characterCount = element.textContent.length;
      console.log(`Character count for ${url}: ${characterCount}`);
      return characterCount;  
    } else {
      console.log(`No element found for ${url}`);
      return 0;  
  } catch (error) {
    console.error(`Error processing URL ${url}: ${error.message}`);
    return 0;  
  }
}  
// ここに抽出したいURLを入れる
const urls = [
  'https://example.com/',
];

// 文字数の抽出と平均文字数を計算する
Promise.all(urls.map(url => countCharacters(url)))
  .then(characterCounts => {
    const totalCharacters = characterCounts.reduce((total, count) => total + count, 0);
    const averageCharacters = totalCharacters / characterCounts.length;

    console.log('Total characters:', totalCharacters);
    console.log('Average characters per URL:', averageCharacters);
  })
  .catch(error => console.error('Error:', error));

```

## 3.実行

ファイルのあるディレクトリ上で以下のコマンドを実行すると、

```terminal
node count_characters.mjs
```

各記事の文字数、総文字数、1URLあたりの平均文字数を抽出できる。
MySQLのSHOW TABLESでテーブルを絞り込む

基本的にDBはターミナルから見てるんだけど、
今までそこまで大規模なテーブル数のシステムをあまりやってなかったのもあり、
絞り込めることを知らなかった…。
公式ドキュメントは細かく読んでおいた方が作業効率が良くなるね…。

## 手順

テーブル名一覧の取得。

```sql
mysql> show tables;
+------------------------------------------------------+
| Tables_in_mydb                                       |
+------------------------------------------------------+
| a_table                                              |
| b_table                                              |
+------------------------------------------------------+
```

LIKE句で絞り込み。

```sql
mysql> show tables like 'b%';
b_table
```

テーブル名指定。

```sql
mysql> show tables where Tables_in_mydb ='a_table';
a_table
```

## 参考

https://dev.mysql.com/doc/refman/8.0/ja/show-tables.html
【Unity】WebGLの出力を確認するローカルWebサーバーアプリ「Web Server for Chrome」の代替えアプリ「Simple Web Server」の紹介

# はじめに
UnityでWebGLをターゲットに出力を確認するために「Web Server for Chrome」Chromeアプリを使用してましたが、Chromeアプリが廃止となるため、「Web Server for Chrome」の代替えとしてOSアプリ版の「Simple Web Server」の紹介します。

# インストール
以下のサイトから、該当のOS（Windows、macOS、Linux）のインストーラーをダウンロードしてインストールしてください。
https://simplewebserver.org/ja/

# 使用方法
環境
OS：Windows10
Unity：2021.3.30f1

手順
1. UnityからWebGLを任意のファルダに出力します。その際に出力を圧縮設定にしていると、起動時にエラーが出る可能性があります。圧縮設定は、「Project Settings」⇒「Player」⇒「Publishing Settings」⇒「Compression Format」を「Disabled」で非圧縮になります。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3553099/f025f4f3-1f84-9f12-d5e2-7250f05b5b99.png)

2. 「Simple Web Server」を起動する。
3. 右下の「新規サーバー」ボタンを押して新規サーバー追加画面に移行します。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3553099/15df4753-2157-bef5-065a-4d071411d377.jpeg" width="30%">
4. サーバー追加画面で「フォルダのパス」を先ほど作成したWebGLを出力したフォルダを指定します。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3553099/4b097133-f763-0c3e-074b-a2752eaeedec.jpeg" width="30%">

5. ポートは任意で変更可能ですがデフォルトの「8080」で問題ないです。
6. その他の設定は後で変更可能なので右下の「サーバー作成」ボタンを押してサーバーを作成します。
7. WebブラウザーのURLに ”http://127.0.0.1:8080” を入れて、UnityのWebGLが起動出来たら成功です。
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3553099/415734de-7b75-a004-6f2f-15f0aab52623.jpeg" width="100%">
無料でAWS CodeWhispererを使ってみよう（個人アカウントのみ）

船井総研デジタルのYookです。

コーディング支援サービス「GitHub Copilot」はよく知られているが、個人アカウントでも有料なので、なかなか手が伸びないですよね。そこで、無料で使える「AWS CodeWhisperer」があることを見つけ、導入してみようと思います。

## AWS CodeWhispererとは
以下の公式ホームページに詳しい内容が載っています。

特徴
* コメントや書きかけのコードから予測して自動生成
* セキュリティースキャン
* オープンソースコードのリファレンストラッカー
* サポートされている言語: Python、Java、JavaScript、TypeScript、C#、Rust、Go、Ruby、Scala、Kotlin、PHP、C、C++、Shell Scripting、SQL



https://aws.amazon.com/jp/codewhisperer/

個人アカウントに限って無料で利用可能！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2885338/de07c8d2-ef83-c867-bb9c-562ec42eee91.png)


## インストール手順
### IDEインストール
ここではVSCodeに導入します。
以下のリンクからダウンロードできます。

https://code.visualstudio.com/Download

### 拡張機能をインストール
VSCodeを開くと、左側のパンネルに「拡張機能」のアイコンがあります。
それをクリックして「AWS Toolkit」を検索します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2885338/c252b88a-65a9-0c95-675d-20c5d68d4662.png)

「install」ボタンを押下し、インストールします。
（以下のイメージはインストール後の状態です）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2885338/3a061bf3-bcca-a11d-7283-7811b462526d.png)

### AWS Builderへログイン
AWS Toolkitのアイコンをクリックし、CodeWhispererメニューから AWS Builderにログインをします。（アカウントを持っていない方はIDを作成します）
ログインすると、すぐ利用することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2885338/ee2ed2b6-71a9-7675-59c7-54190c7a097f.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2885338/e0f7b065-d4ac-b633-a6c2-375ac6a6fd42.png)


## じゃあ、使ってみよう
作ってもらいたいことをコメントに書いて改行をすると、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2885338/4a195394-404a-db3c-def8-1488e31542a4.png)

提案コードが表示されます。
そして、その上にToolbarが現れることがわかります。
マウスで矢印をクリックすると、次の提案コードの確認ができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2885338/d46a5447-e1aa-8553-bdb8-8f83a26c8507.png)

Toolbarに書いてある通り、使いたいコードがある場合、「Tab」キーを押すことでエディターに反映されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2885338/5f78345f-d7d9-cf1f-324e-9d9a595544f6.png)

以下のように、コメントにせず関数名を入力するだけでも関連づいたコードを提案してくれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2885338/45e3d514-0908-9aa7-1cdc-ab9e2bc78e2e.png)


## 感想
* とにかくお金がかからないポイントは最高！
* GitHub Copilotにない「セキュリティーチェック」と「オープンソースコードのリファレンストラッカー」のサービスは頼りになる
* GitHub Copilotでは、提案コードを別のタブを開き、一目で確認できるような機能があるが、CodeWhispererにはないため、少し不便かな

以上、AWS CodeWhispererのまとめでしたー
【GoogleBard】大幅アップデート？


　どうも、カーブミラーです。

　今回は、GoogleBardが大幅アップデート。画像認識、公開リンク、メールアクセス、回答のカスタマイズ。使ってみました。

:::note info
本記事は、
　ChatGPTは
　　関係ありません。
　　　あしからず。
:::

　詳しくは、
　　こちらをどうぞ。
[Googleの無料AI｢Bard｣に大アプデ：画像認識、シェア機能、そして待望のメールアクセス](https://www.gizmodo.jp/2023/09/google-bard-sept23-update.html)
***

　ビジュアルが
　　全然、変化していないので、
　　　変更場所を
　　　　探してしまいましたw

　変わったところは、
　　プロンプト入力枠の左側。
　　　四角い風景マーク？が
　　　　あるくらい。

　これが、
　　カメラ起動するか、
　　　画像ファイルを取り入れるか
　　　　選ぶところですね。

　内容は、以下のとおり。
***
　画像認識が可能に
　　なったそうです。

　英語版では、
　　すでに使えていましたが、
　　　日本語でも使用可能に
　　　　なったそうです。

　画像認識は、
　　それだけならば、
　　　Googleレンズで充分です。
　　　　どうしたいのかを
　　　　　入力しないと
　　　　　　いけませんし。
***
　シェア（公開リンク）機能は、
　　私のスマホのブラウザでは
　　　利用方法が不明。
　　　　ChatGPTの共有リンクと
　　　　　似た感じみたいです。
　　　　　　使ったこと、
　　　　　　　ないですけどw
***
　メールアクセスは、できる。
　　でも、Web版を呼び出すから
　　　いちいちズームアップの
　　　　必要がある。不満。
　ちなみに、GoogleDocumentsに
　　エクスポートも可能。
***
　回答のカスタマイズは、
　　すでに得た回答をどうするか。
　　・短くする
　　・長くする
　　・シンプルにする
　　・カジュアルな表現にする
　　・専門的な表現にする
　これは、これまでプロンプトで、
　　調整してきたことを
　　　意識する必要がなくなる
　　　　ので、Good。
　でも、選ぶと、
　　いちいちRegenerateするので
　　　そこで時間が取られるし、
　　　　内容も納得いかない。
　　　　　これは人によるのかも。
***
　以前にあった
　　回答の最後に、
　　　Google検索のボタンが
　　　　なくなりましたね。
***
　とりあえず、
　　使用感は、
　　　こんなところです。

　回答のカスタマイズは、
　　最初から、選択させて、
　　　プロンプト入力を
　　　　させた方がいい、と思う。

　個人的には、
　　そこよりも、
　　　回答候補の選択したら
　　　　すぐにそれを表示して
　　　　　欲しいんですけどね。

　いちいち“他の回答案を表示”を
　　タップしないといけないのは、
　　　手間です。

　英語圏の人は、
　　許容範囲なのかしら？

　今回は、以上です。
pdf2htmlEXがbrewで使えなくなっていたのでDockerで使ってみた

# はじめに
以前使っていた`pdf2htmlEX`が`brew`で入らなくなっていました。

```
% brew install pdf2htmlex
（中略）
Warning: No available formula with the name "pdf2htmlex". Did you mean pdf2image?
==> Searching for similarly named formulae and casks...
==> Formulae
pdf2image

To install pdf2image, run:
  brew install pdf2image
```

調べてみるとメンテナーが変わって、開発環境がないためhomebrewのビルドスクリプトを開発できないとのことでした。

https://github.com/pdf2htmlEX/pdf2htmlEX/wiki/Building

仕方ないので、代わりにDockerで使えるようにしてみました。すご〜く簡単です。


# セットアップ


## Dockerのインストール
インストール方法はお任せします。今回はDocker Desktopを用います。

https://docs.docker.com/desktop/install/mac-install/

## Dockerhubからイメージをpull
Dockerhubにイメージがありますのでpullしてきます。`:latest`を指定するとうまく落ちなかったので、最新のタグをつけてpullしました。

```
docker pull pdf2htmlex/pdf2htmlex:0.18.8.rc2-master-20200820-alpine-3.12.0-x86_64
```


## 実行
早速実行してみました。簡単です。

```
docker run -ti --rm -v "`pwd`":/pdf -w /pdf pdf2htmlex/pdf2htmlex:0.18.8.rc2-master-20200820-alpine-3.12.0-x86_64 --zoom 1.3 <input>.pdf
```

入力ファイルと同じディレクトリに同じファイル名のhtmlが書き出されます。


## エイリアスを張る
毎回このコマンドを入力するのは大変なので、エイリアスを設定します。
```
alias pdf2htmlEX='docker run -ti --rm -v "`pwd`":/pdf -w /pdf pdf2htmlex/pdf2htmlex:0.18.8.rc2-master-20200820-alpine-3.12.0-x86_64'
```

これで、`pdf2htmlEX <input>.pdf`と実行するだけでHTMLファイルが作成できます。必要に応じて`pdf2htmlEX --zoom 1.3 <input>.pdf`のようにオプションも利用できます。

# 参考
https://github.com/pdf2htmlEX/pdf2htmlEX/wiki/Download-Docker-Image
pythonの引数にlambda関数を使うと便利だった

```py:データ
numbers = [['1', '40'], ['4', '13'], ['3', '14'], ['25', '30'], ['17', '20'], ['21', '22']]
```

# リストの要素をキーとして最大値のリストを取得
- リストの1つ目の要素をキーとして最大値のリストを取得
```py
m = max(numbers, key=lambda x: int(x[0]))
print(m)
```
```:実行結果
['25', '30']
```

- リストの2つ目の要素をキーとして最大値のリストを取得
```py
m = max(numbers, key=lambda x: int(x[1]))
print(m)
```
```:実行結果
['1', '40']
```

# リストの要素をキーとして昇順に並び替える
- リストの1つ目の要素をキーとして昇順に並び替える
```py
s = sorted(numbers, key=lambda x: int(x[0]))
print(s)
```
```:実行結果
[['1', '40'], ['3', '14'], ['4', '13'], ['17', '20'], ['21', '22'], ['25', '30']]
```

- リストの2つ目の要素をキーとして昇順に並び替える
```py
s = sorted(numbers, key=lambda x: int(x[0]))
print(s)
```
```:実行結果
[['4', '13'], ['3', '14'], ['17', '20'], ['21', '22'], ['25', '30'], ['1', '40']]
```

# リストの要素の一部を取得
- リストの1つ目の要素が２で割り切れるリストを取得
```py
f = list(filter(lambda x: int(x[0]) % 2 == 0, numbers))
print(f)
```
```:実行結果
[['4', '13']]
```

- リストの2つ目の要素が２で割り切れるリストを取得
```py
f = list(filter(lambda x: int(x[1]) % 2 == 0, numbers))
print(f)
```
```:実行結果
[['1', '40'], ['3', '14'], ['25', '30'], ['17', '20'], ['21', '22']]
```

## 補足
こんなことも一応はできる
- リストの2つ目の要素が２で割り切れるリストを取得し、リストの2つ目の要素をキーとして昇順に並び替える
```py
f = sorted(list(filter(lambda x: int(x[1]) % 2 == 0, numbers)), key=lambda x: int(x[1]))
print(f)
```
```:実行結果
[['3', '14'], ['17', '20'], ['21', '22'], ['25', '30'], ['1', '40']]
```
シグネチャとインターフェイスの違い

「シグネチャ」と「インターフェイス」は、特にTypeScriptの文脈で考えると、関連性がありますが、異なる概念です。
以下に、それぞれの違いを簡潔に説明します。

## シグネチャ

これは、あるオブジェクトのプロパティ（属性やメンバー変数とも呼ばれる）が持つべきデータ型を指定するものです。

### 例
```TypeScript
name: string;
```
は、nameというプロパティが文字列型(string)であることを示すシグネチャです。


## インターフェイス

インターフェイスは、オブジェクトやクラスが持つべきプロパティやメソッドの集合体を定義するものです。
この定義内には、それぞれのプロパティやメソッドのシグネチャが含まれます。

```TypeScript:例:
interface IPerson {
  name: string;
  age: number;
  greet(): void;
}
```

このIPersonインターフェイスは、nameという文字列型のプロパティ、ageという数値型のプロパティ、そしてgreetという戻り値がvoidのメソッドを持つことを定義しています。

- interface
    -  TypeScript で新しいインターフェースを定義するためのキーワードです。

- IPerson
    - インターフェースの名前です。`I` で始まる命名は、一般的にインターフェースを示す慣習として使用されることがあります。

## 結論

プロパティのシグネチャは、特定のプロパティがどのようなデータ型を持つかを示すものです。

インターフェイスは、複数のプロパティやメソッドのシグネチャをまとめた定義のことです。
インターフェイスは、特定のオブジェクトやクラスが持つべき構造や動作を定義するものと考えることができます。

インターフェイスは、プロパティやメソッドのシグネチャの"集合"と考えることができます。一方、プロパティのシグネチャは、その集合の一部、つまり1つの要素に過ぎません。
[ GIF ] Matplotlib でムービー作成

pythonで動画を作成する方法をメモします．
matplotlib.animationを使用しました．

## ライブラリ
```python:
import matplotlib.animation as ani
import matplotlib.pyplot as plt
```

## 配列を作成
以下の配列 images に画像を格納していく．
```python:
images = []
```

## 画像をプロット
- 動画にする画像を作成
>画像を連続で表示させることで動画化します．
>```python:
>image = ax.plot(x, y, color = "steelblue")
>```
>:::note warn
>色を指定しないと画像一枚ごとに線の色が変化してしまう
>:::
>複数のグラフを重ねることも可能
>```python:
>image_2 = ax.plot(x, y_2, color = "orangered")
>```
>
>※余談ですが， steelblue, orangered が matplotlib のデフォルトカラーに近い気がしています．

## タイトル作成
::: note alert
通常通りタイトル設定はできない．
:::
```python:
# これだと反映されない
ax.set_title("title t = {}".format(t))
```


:::note info
テキスト入力を使用する．
:::
```python:
# テキスト入力する
title = ax.text(x, y, "title t = {}".format(t))
```

## 配列に格納
- 上で作成した画像とタイトルを配列に格納する．
>```python:
>images.append(image + image_2 + [title])
>```

## プロット
- 適当な fig に入れます．
>```python:
>ani = ani.ArtistAnimation(fig, images, interval = 100)
>```

## その他設定
- 凡例
>凡例をセットするときは次のようにプロットしたグラフ順に配列を作成する．
>```python:
>ax.legend(["label 1", "label 2"])
>```

- 画像サイズ
>次のように調整します．
>```python:
>fig.subplots_adjust(left = 0.2, right = 0.95, bottom = 0.15, top = 0.9)
>```

- 保存方法
>    - GIFの場合は，writer = "pillow" で保存できる．
>dpi , fps はお好みで
>```python:
>ani.save("movie.gif", writer = "pillow", dpi = 300, fps = 30)
>```
>  - MP4の場合は writer = "ffmpeg" で保存できる．
>（別途 ffmpeg をダウンロードする必要あり）
>```python:
>ano.save("movie.mp4", writer = "ffmpeg")
>```


:::note ifo
メモリ，軸，ラベルの設定は通常のものが使用できます．
:::

## 作成例
- 作成したもの
>時々刻々と変化するsin波とcos波を同時にプロット
>
>
- コード
```python:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as ani

#. -- Time parameter --
it_min = 0
it_max = 100
t_min = 0
t_max = 1
dt = t_max/it_max


#. -- Coordinate --
x_min = 0
x_max = 10
dx = 0.1
x = np.arange(x_min, x_max, dx)


#. -- Graph Setting --
fig, ax = plt.subplots(figsize = (6, 6))
images = []


#.  -- Time loop --
for it in range(it_min, it_max) :
    
    #. function
    t = dt*it
    y = np.sin(x - t)
    y2 = np.cos(x - t)
    
    #. plot 
    image_1 = ax.plot(x, y, color = "steelblue")
    image_2 = ax.plot(x, y2, color = "orangered")
    title = ax.text(4, 1.20, "t = {:.1f}".format(t), fontsize = 16)
    images.append(image_1 + image_2 + [title])

#. Setting
ax.legend(["sin", "cos"], loc = "upper right")
fig.subplots_adjust(left = 0.1, right = 0.95, bottom = 0.1, top = 0.9)

#. Save
ani = ani.ArtistAnimation(fig, images, interval = 1000)
ani.save("sin_cos.gif", writer = "pillow", fps = 30)
#ani.save("sin_cos.mp4", writer = "ffmpeg", fps = 30, dpi = 300)
```

- 実行結果
![sin_cos.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3089106/c3a66396-8c49-c188-e166-230c3d0c542f.gif)

不具合？なのかわからないのですがGIFをクリックするとスムーズに再生されます．