OmniAICreator/Qiita-1.07M huggingface dataset:
達人に学ぶDB設計徹底指南書 を読んだ感想

## はじめに
[達人に学ぶDB設計徹底指南書](https://www.amazon.co.jp/%E9%81%94%E4%BA%BA%E3%81%AB%E5%AD%A6%E3%81%B6DB%E8%A8%AD%E8%A8%88-%E5%BE%B9%E5%BA%95%E6%8C%87%E5%8D%97%E6%9B%B8-%E5%88%9D%E7%B4%9A%E8%80%85%E3%81%A7%E7%B5%82%E3%82%8F%E3%82%8A%E3%81%9F%E3%81%8F%E3%81%AA%E3%81%84%E3%81%82%E3%81%AA%E3%81%9F%E3%81%B8-%E3%83%9F%E3%83%83%E3%82%AF/dp/4798124702/)を読んだのでアウトプット記事を書いていきます。


## 学んだこと
### 第一章
- 3層スキーマ
  - 外部スキーマ
  ユーザから見たDB。
  - 概念スキーマ
  開発者から見たDB。論理設計にあたる部分
  - 内部スキーマ
  DBMSから見たDB。物理設計にあたる部分
### 第二章
- 論理設計→物理設計の順に行う
- 論理設計のステップは以下
    1. エンティティの抽出
    1. エンティティの定義
    1. 正規化
    1. ER図の作成
- 物理設計のステップは以下
    1. テーブル定義
    1. インデックス定義
    1. ハードウェアのサイジング
    1. ストレージの冗長構成の決定
    1. ファイルの物理配置の決定
- バックアップ設計
バックアップ方式は、「フルバックアップ＋差分バックアップ」または「フルバックアップ＋増分バックアップ」が一般的。
- リカバリ設計
  - バックアップファイルを戻す作業をリストア、そのファイルに対してトランザクションログを適用して変更分を反映する作業をリカバリ
### 第三章
- テーブルの構成要素
  - キー
    - 主キー
      - レコードを一意に識別するためのもの
    - 外部キー
      - 外部キーがある場合、データの削除は子から順に行う方が良い
  - 制約
    - NOT NULL制約
    - 一意制約
    - CHECK制約
#### 正規化について
- 正規化とはDBのデータの冗長性を排除し、一貫性と効率性をもったデータ形式にすること。正規形は第5レベルまであるが、普通は第3正規形まで理解すればOK
  - ボイスーコッド正規形：非キーからキーへの関数従属をなくした状態にする。分解時に気をつけないと不可逆な操作となることがある
- 第4正規形：多値従属性が複数存在するテーブルを分割する
- 第5正規形：関連と関連エンティティを1対1になるようにテーブルを分割する
#### 正規化まとめ
- 第三正規形までは行う
- 関連エンティティが存在する場合は、関連とエンティティが1対1に対応するよう注意する
- メリット
  - テーブルの持つ意味が明確になって、開発者が理解しやすくなる
  - データの冗長性が排除で、更新時の不整合を防止
- デメリット
  - テーブルの数が増えるため、SQL文で結合を多用することになり、パフォーマンスが悪化
### 第四章
- ER図の代表的なフォーマットは、「IE表記法」と「IDEFIX」
  - IE表記のほうが簡素で概略把握しやすい
  - IDEFIXはかなり細かく記述できる
- 1対1
  - あまり見かけない
  - 二つのテーブルのレコードが1対1に対応する場合、二つのテーブルの主キーが一致する事になる為、その場合は一つのテーブルにまとめても問題ない
- 1対多
  - 最も良くあるタイプ
  - 基本的に正規化によって生まれる関連はこのカテゴリに属する
- 多対多
  - RDBのお約束として、基本的に多対多の関連は作ってはならない
  - 中間テーブルを作成して対応する
### 第五章
- 正規化されたテーブルへのSQLは結合を多用することになるので、非常にパフォーマンスが悪くなる
- 非正規化のリスク
  - 非正規化は、検索のパフォーマンスは向上させるが更新のパフォーマンスを低下させる
  - データのリアルタイム性（鮮度）を低下させる
  - 後続の工程で設計変更すると、手戻りが大きい
### 第六章
- インデックスは、SQLチューニングの手段として非常よく使う
- 最短距離を探してくれる
  - 「ここに行きたい」と入力するカーナビと同じ
  - コストベース
- 統計情報収集は原則、夜間帯に実施する
### 第七章
- 非スカラ値
  - 第一正規形すら満たしていない
- ダブルミーニング
  - 列の意味が行毎に違っている
  - レコードは変数ではない
- テーブル分割
  - 水平、垂直分割はNG
  - 集約関数で対応
- 不適切なキー
  - 固定長と可変長を混同して使う
- ダブルマスタ
  - 顧客マスタが複数ある
    - システム統廃合によって起こる
### 第八章
- 主キーが決められない・不十分なケース3つ。解決策は、代理キー
  - 入力データに一意なキーがそもそも存在しない
  - 一意キーはあるが、サイクリックで使いまわされている
  - 一意キーはあるが、途中で指す対象が変化する
- 代理キー（サロゲートキー）で解決
  - なるべくやらない方がいい。ER図でわからなくなる
- 自然キーで解決
  - タイムスタンプ、インターバルを使用
- アドホック(場当たり的）な集計キー
- 多段ビュー
  - ビューは「クエリの缶詰」
  - DBMSはビューのSELECTとテーブルのSELECTをマージして実行する
  - 「ビューの背後にあるテーブルの存在を、常に意識せよ」
  - ビューは原則として1段にとどめる
### 第九章
- RDBでは木構造のデータを表現するのが苦手
- 入れ子区間モデルは、いずれ近い将来において主流となるモデルだと予想される

## 良かったこと
入門書には詳しく書いていないアンチパターンについて学べた。プログラミングよりDBの設計の方が大切であると理解できた

## 難しかったこと
全体的に内容が難しかったです。

小規模な個人開発もしたことがない為、現段階では全体像が掴みにくかったです。

6~9章は曖昧な部分が多いので都度見直して知識を定着させます。
Fragmentの作成法方


Fragmentを作成する手順を書く。Fragmentを作成を作成するには`onCreateView`にてXMLで定義したViewを`inflate`で読み込ませる。次に作ったビューを返すことによってできる。その後、`onViewCreated`では各ビューに対して初期設定を決めることで、ボタン処理や画面の切り替えを可能にする。
ユーザーが画面から離れた場合は`onDestroyView`でbindingをnullにして、画面の処理を実行しないようにする。
```kotlin
private lateinit var binding: TopFragmentBinding

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
    binding = TopFragmentBinding.inflate(inflater, container, false)
    return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    
    // 初期設定を記述する
}

override fun onDestroyView() {
    super.onDestroyView()

    binding = null
}
```

下記のライブラリを使用すれば、onCreateViewとonDestroyViewの記述を省略吸うことができる。

https://github.com/Zhuinden/fragmentviewbindingdelegate-kt

```gradle
implementation("com.github.Zhuinden:fragmentviewbindingdelegate-kt:1.0.0")
```
下記の1行でビューをバインドすることができ、onDestroyViewでの処理も行ってくれる。
```kotlin
private val binding by viewBinding(TopFragmentBinding::bind)
```
#### 参考

https://qiita.com/yuki-naka/items/0b385c3c8faf6b48d891

https://qiita.com/maxfie1d/items/296586e6bb929474142f
PlayerInputを用意しなくてもInputActionAssetの入力を取得できる話

## Unityの`InputSystem`を使った入力情報の利用方法

Unityの`InputSystem`を使用して入力情報を利用する場合、次の3つの方法があります。

1. `PlayerInput`からInputActionを取得する
2. `PlayerInput`のコールバックを受け取る
3. 独自に`InputActionMap`を定義する
3. `InputActionAsset`からC#コードを生成し使用する

これらの方法はそれぞれのメリットがありますが、`PlayerInput`を使用する場合、同じオブジェクトで実行するため、誰が`PlayerInput`を持つのかを決める必要があり、少し面倒に感じることがあります。

## `InputSystem.actions` API

最近?のバージョン（おそらく`Input System 1.8.0`）から、新しいAPIとして`InputSystem.actions`が追加されました。このAPIを使用することで、`Project Settings`内の"Project-Wide Actions"に指定された`Input Action Asset`をゲーム実行中に有効化し、コード側から直接取得できるようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12772/f2e0c6a3-6d01-81b1-2d5b-13af5becbde1.png)

また、**Unity6**のプロジェクトでは、最初から `InputActionAsset` が用意されるようになりました。このアセットは最初から "project wide actions"に登録されており、`Move`や`Interact`などの基本的なコマンドが最初から利用できるようになっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12772/87b28fb5-a119-0fb7-81c9-d0fc5341a6e2.png)


### 利用方法

"Project-Wide Actions"に設定された`Input Action`は、ゲーム実行中に有効化され、以下のように`InputSystem.actions.FindAction`を使用して取得できます。

例えば、キャラクターの移動情報を取得する場合は、以下のように記述します。

```csharp
public class Player : MonoBehaviour
{
    private InputAction _inputMove;
    private CharacterController _controller;
    private float _speed = 5;

    private void Awake()
    {
        TryGetComponent(out _controller);
        _inputMove = InputSystem.actions.FindAction("Move");
    }

    private void Update()
    {
        var inputValue = _inputMove.ReadValue<Vector2>();
        var direction = new Vector3(inputValue.x, 0, inputValue.y).normalized;
        var velocity = direction * (Time.deltaTime * _speed);
        _controller.SimpleMove(velocity);
    }
}
```

もしくはイベントを登録します。
```csharp
    private void Awake()
    {
        _interactInput = InputSystem.actions.FindAction("Interact");
        _interactInput.started += OnInteract;
    }

    private void OnDestroy()
    {
        _interactInput.started -= OnInteract;
    }

    private void OnInteract(InputAction.CallbackContext obj)
    {
        // do something.
    }
```
Azure クイックスタート

## はじめに
`Azure`はMicrosoftが提供するクラウドサービスです。この記事では、`Azure`アカウントの作成方法を簡単に説明します。まだ使ったことがない方や、気になっている方は、ぜひチェックしてみてください！

## アカウント登録
`Azure`を始めるには、まずアカウントを作成する必要があります。
以下の手順に沿って、簡単に説明します。
#### 1. Azure公式サイトにアクセスし、"Azureを無料で試す"をクリックする
https://azure.microsoft.com/ja-jp/pricing/purchase-options/azure-account/

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2703371/418227d6-aba5-5aa6-aa45-88b5c4e1804b.png" width=90%>

#### 2. Microsoftにログインする

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2703371/1fedca25-af3a-659d-e79c-4e1e394c85a6.png" width=70%>

#### 3. Azureアカウントを作成する

:::note warn
クレジットカードが必要です
:::
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2703371/b934998e-743c-a55c-2895-ffebc58ef30e.png" width=90%>

#### 4. Azureポータルにログインする
以上で、アカウント作成が完了しました！
ポータルにログインし、以下の画面が表示されれば成功です。

https://portal.azure.com/

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2703371/8d87936e-c3c8-ef6a-8215-29a57ad55d0c.png" width=90%>

## 補足
#### 1. 200ドルのクレジット
新規登録時に200ドル（約3万円）のクレジットが付与されます！これを使って、様々なサービスを試すことができますね。

個人的には`Azure OpenAI Service`や`Azure Machine Learning`が特におすすめです（どちらも結構コストがかかるため、クレジットを活用するのにピッタリです）。

:::note warn
なお、クレジットの有効期限は30日間です。それ以降は無効となるため、ご注意ください。

ちなみに私は、全て使い切ることができませんでした…
:::
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2703371/29152e96-0dd2-5659-7a8b-270a942eb62b.png" width=70%>

#### 2. 無料トライアル
更に、**12か月間無料**と**常時無料**の2種類のサービスがあります。
これを活用して、自作アプリを`Azure App Service`にホストしてみるのも面白そうですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2703371/95e12591-7793-25d5-0af8-9b745f669118.png)
[競プロ]AtCoderでの削除不要で高速なデバッグ方法

# 結論

環境変数で条件分岐させることで、提出時に削除不要かつ速度のオーバーヘッドを低く抑えることが可能です

```python
import os

IS_ATCODER = bool(int(os.getenv("ATCODER", "0")))

def debug(*args, **kwargs) -> None:
    if not IS_ATCODER:
        print(*args, **kwargs)

for i in range(10 ** 7):
    debug(i)
    ...
```

# はじめに
競技プログラミングのデバッグはどのように行なっていますか？

最も簡単な方法はprintデバッグでしょう

```python
for i in range(10 ** 7):
    print(i)
    ...
```

しかしこの方法には大きな欠点があります。

それは、AtCoderに提出する際にprint文を削除する必要があり、削除を忘れるとWAを食らってしまいます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678160/d5c9d595-eeef-51eb-f9c7-33486e79f2f3.png)
私自身、何回かやらかしてます、、、

# stderr（標準エラー出力）

削除する必要がないデバッグ方法として、stderrも候補です

```python
import sys

def debug(*args, **kwargs) -> None:
    print(*args, **kwargs, file=sys.stderr)

for i in range(10 ** 7):
    debug(i)
    ...
```

しかし、この方法も標準エラー出力にかかる時間がオーバーヘッドになるため、TLEになるリスクがあります。

# 環境変数で実行環境を判別して条件分岐

さて、AtCoderの環境には以下の環境変数が指定されています（言語には依らないと思いますが、Python (PyPy 3.10-v7.3.12)で調査しています。なお公式で明言されているわけではないと思うので、利用は自己責任でお願いします）

| 環境変数名 | 値 |
| --- | --- |
| PATH | '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' |
| LANG | 'C.UTF-8' |
| 'ATCODER' | '1' |
| 'HOME' | '/home/runner' |

ちなみに、以下のコードで調べることができます
```python
import os
print(os.environ)
```

この内、`ATCODER`の値を取得することで、環境を判別することが可能です

```python
import os

IS_ATCODER = bool(int(os.getenv("ATCODER", "0")))

def debug(*args, **kwargs) -> None:
    if not IS_ATCODER:
        print(*args, **kwargs)

for i in range(10 ** 7):
    debug(i)
    ...
```

そして、この方法では標準エラー出力のようなI/Oが発生しないため、高速であることが期待できます

# 速度比較
実際に幾つかのコードで速度を比較してみました

## 1. デバッグなし

```python
for i in range(10 ** 8):
    a = i  # ダミーの処理
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678160/04e698da-6266-b7a2-68ec-e1b8991966a6.png)


## 2. stderrでデバッグ

```python
import sys

def debug(*args, **kwargs) -> None:
    print(*args, **kwargs, file=sys.stderr)

for i in range(10 ** 8):
    a = i  # ダミーの処理
    debug("hello", a)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678160/0543b8dc-c28b-3b16-17c7-bb54100b26da.png)

1より明らかに遅くなったことがわかります

## 3. 環境変数で条件分岐してデバッグ

```python
import os

IS_ATCODER = bool(int(os.getenv("ATCODER", "0")))

def debug(*args, **kwargs) -> None:
    if not IS_ATCODER:
        print(*args, **kwargs)

for i in range(10 ** 8):
    a = i  # ダミーの処理
    debug("hello", a)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678160/83589b67-cbc3-b2ba-5c6c-89701498e5f8.png)

2より圧倒的に高速で、1とほぼ同じ速度（+33ms）で処理することができました

## 4. 環境変数で条件分岐してデバッグ（改良）

ちなみに、lambda式にすると+2msまでオーバーヘッドを抑えることができました

```python
import os

IS_ATCODER = bool(int(os.getenv("ATCODER", "0")))

debug =  (lambda *args, **kwargs: None) if IS_ATCODER else print

for i in range(10 ** 8):
    a = i  # ダミーの処理
    debug("hello", a)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678160/585ce2ca-9d40-2fc9-1769-acf849532708.png)

個人的には、可読性を優先した3の書き方で良いと思いますが、とにかく速度を求めたい方はこちらでも良いでしょう

# まとめ
ぜひ、ご活用ください。
それでは、よい競プロライフを！
はじめに

# はじめに

###### Salesforceエンジニア、VBAエンジニアです！！
それに伴いTipsなど投稿していきます！！

開発初心者～中級者の手助けになることを目標としてて、なかなかスキルアップって難しいよね･･･うまいことコード見つからないし～って･･･
目安としては、プログラムの概念が分かる人のステップアップ用になればと思ってるよ！！

どうぞ、お力になれることを目標に、更新していきます。
励みになるから、フォロー＆いいねしてほしいな！！！
俺のシンボリックリンクがシンボリックリンクじゃない…だと…win11 home

::: note info
**本記事の概要**
1. 愛する後輩たちに向けた紹介記事
1. XAMMPのhtdocsにシンボリックリンクを作ることで開発場所の自由度を上げる方法を紹介
1. そのうち使うlinuxのコマンド`cd` `ls -l` `ln -s`コマンドをついでに使える

:::

## PHPの開発は好きなところでやりたい
### はじめに
:::note info
環境
OS：Windows 11 Home
開発環境：XAMMP
各種設定ファイル：デフォルトまま
ターミナル：Git Bash
:::
XAMMPを使用した開発をする際に
ブラウザ上で表示をするにはC:/xammp/htdocsいかにプロジェクトフォルダを配置する必要があります。
何も考えずに開発をすると下記のようになります。
1. **htdocs内のプロジェクトフォルダ内でそのまま開発する**
1. **他所で開発したデータをコピーして配置する**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3562770/ac0d5616-f48e-1a68-2a75-04da1aa20cdc.png)

久しぶりにデータを除きに行くと、

> あれ…これが最新でいいんだっけ？

となることしばしば、Githubからクローンしてもいいんですが、そこまではちょっと面倒。
可能であれば、開発はいつもここでという場所を作っておきたいところ。

### シンボリックリンクを作ろう。mklinkではなくlnコマンドで
この課題の対処として、まずxammpの設定ファイルを変更する手法があります。[^1]

[^1]:https://simpleonesoft.com/blog/xampp_localdev/

:::note warn
**判定：却下**
いちいちやりたくない。設定方法を忘れる。設定したことすら忘れる。
:::
ということで、別の手法をとりたいです。本当は設定ファイルをかっこよく使いこなしたいが…
そこでシンボリックリンクを使った方法です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3562770/057b32d8-33ba-eddc-7378-cc80f18bc0c1.png)

:::note info
**シンボリックリンクって？**
ファイル・フォルダのリンクを作成するが、
作成した場所にあるもののようにアクセスできる状態を作るもの
例えばhtdocs下に開発用のディレクトリにおけるフォルダapp1のシンボリックリンクを作成した場合
htdocs/app1としてファイルを参照・編集できるようになるのです。
:::

windowsでシンボリックリンクを作る際は
1. **`mklink`コマンドを使用[cmdかPowershell]** [^2]　※要管理者権限
1. **`ln`コマンドを使用する[Git Bash]** [^3]
[^2]:https://blackmagicdesign-creatorscom.jp/cmd-mklink/
[^3]:https://qiita.com/takuyanin/items/3682ac19bbbc21792849

があげられます。
linuxのコマンドの方は色んな所で使うので、`ln`コマンドを実行することにします。

## タイトル回収「俺のシンボｒ」
### コマンド実行した結果
早速シンボリックリンクを作ってみました。
```bash
ln -s "/c/Users/Watashi no Name/dev/sample_project" "/c/xammp/htdocs/sample_project"
```
実行するとhtdocs下にsample_projectが現れました。
めだたしめでた…くなかった。
実はこれ、リンクなんかじゃないんです。
ファイルの変更が反映されない。

### なにこれ
シンボリックリンクか確認してみる
シンボリックが正しく作成されていた場合、`ls -l`で確認すると　`リンク先->リンク元`として表示されるそうなので見てみましょう。`-l`オプションを忘れずに。

```bash
# cdコマンドでhtdocsに移動
cd /c/xammp/htdocs
# ls -l でフォルダ内のファイル・フォルダ一覧を表示
ls -l
```
結果は
```bash
...
...
lrwxrwxrwx 1 user user 12 Jan 1 12:34 sample_project
...
```
`リンク先->リンク元`の形式で表示されない…つまりこれハードコピーされた状態なんです。なんでや！

## 疑問の解消・解決手法 
windowsのデフォルトはシンボリックリンクの作成がハードコピーになるようです。
グループポリシーを変更してシンボリックリンクの作成を許可する必要があると。
win11 proの場合はその設定を変更するツールが標準で使えるらしいが、homeだとそれがない。
homeの場合は外部のソフトを使うことで変更が可能です。
↓先人の教えありがたいやつ

https://qiita.com/ucho/items/c5ea0beb8acf2f1e4772

やることは簡単でした。↑の記事に従い
1. polseditで権限付け
1. 環境変数の追加＠GitBash

サインアウト➡ログインをして
サイドシンボリック作成のコマンドを実行してみる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3562770/f5874676-c77c-eb9a-a66e-6888fc902c04.png)
アイコンがなんかリンクっぽくなった。いけてそう！
もう一度`ls -l`で確認すると
```bash
ls -l
```
```bash
...
...
lrwxrwxrwx 1 user user 12 Jan 1 12:34 sample_project -> xxxxxxxxxxxxx
...
```
矢印付きでちゃんとシンボリックリンクが作成できました。
どちらか一方にデータを追加・編集すると、もう一方に反映されていることが確認できます。
開発を別のフォルダで進めてもxammpのhtdocs内にあるもののように参照されるので、一度シンボリックリンクを作ってしまえばあとはよしなに出来ちゃうぞと。
分類タスクの評価指標をわかりやすく解説！

こんにちは！今日は、機械学習の分類タスクで使われる評価指標について説明します。これらの指標は、モデルがどれだけうまく分類できているかを測るためのものです。一緒に学んでいきましょう！

## 1. 正解率（Accuracy）

正解率は、全体の中でどれだけ正しく分類できたかを表します。例えば、100個のデータのうち80個を正しく分類できたら、正解率は80%です。

計算式：
\[
\text{正解率} = \frac{\text{正しく分類した数}}{\text{全体の数}}
\]

## 2. 適合率（Precision）

適合率は、モデルが「正」と予測したものの中で、実際に正しかったものの割合です。例えば、10個を「正」と予測して、そのうち8個が実際に正しかったら、適合率は80%です。

計算式：
\[
\text{適合率} = \frac{\text{正しく「正」と予測した数}}{\text{「正」と予測した数}}
\]

## 3. 再現率（Recall）

再現率は、実際に正しいものの中で、モデルが「正」と予測できたものの割合です。例えば、実際に正しいものが10個あって、そのうち7個を「正」と予測できたら、再現率は70%です。

計算式：
\[
\text{再現率} = \frac{\text{正しく「正」と予測した数}}{\text{実際に正しい数}}
\]

## 4. F1スコア（F1 Score）

F1スコアは、適合率と再現率のバランスを表します。適合率と再現率の両方が高いほど、F1スコアも高くなります。

計算式：
\[
\text{F1スコア} = 2 \times \frac{\text{適合率} \times \text{再現率}}{\text{適合率} + \text{再現率}}
\]

## まとめ

これらの指標を使うことで、モデルの性能を多角的に評価できます。正解率だけでなく、適合率や再現率も確認することで、より良いモデルを作ることができますよ！
（初心者向け）CLI操作を快適にするためのTips

## はじめに
こんにちは、mamedogsといいます。
5年ほど前にWebエンジニアに転職したのですが、当時はLinuxのCLI操作が苦手で、コマンドを打つたびに手が止まってしまうこともありました。
「もっとスムーズに操作したいな」と思うことが何度もありました。

そこでこの記事では、当時の自分に教えたいと思う、CLI操作に関する知っておいたほうが良い知識と便利なショートカットについてまとめてみました。同じようにCLI操作に悩んでいる方の助けになれば嬉しいです！

### 知っていたほうが良いショートカットやコマンド
「Linux ショートカット」というキーワードで検索すると、たくさんのショートカットキーが紹介されている記事が見つかると思います。ただ、初心者の方にとっては、すべてを一度に覚えるのは難しいですし、どのショートカットが本当に役立つのか分かりづらいこともありますよね。
そこでこの記事では、個人的に重要度が高いと思われるショートカットキーだけを厳選してご紹介します。まずはここから覚えてみてください！


#### Tabキーの活用
Tabキーを押すと、ファイルパスやファイル名を自動補完してくれます！

階層の深いディレクトリの中にあるファイルにアクセスする場合、パスを手動で入力すると時間がかかりますが、Tabキーを使えば簡単に補完できて便利です。

例えば、以下のようなディレクトリ構造で、3階層下にある test.txt を開きたい場合を考えてみましょう。
```shell:shell
root: ~ $ tree
.
└── dir1
    └── dir2
        └── dir3
            └── test.txt

```
このとき、vim コマンドを入力してファイルを開こうとする際に、Tabキーを押すだけでパスが自動的に補完されます。わざわざパスを全部入力する手間が省けるので、とても効率的にコマンドを記述できます。

以下は、「vim d」まで打って後はTabキーを連打しています。

![tab1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499266/9e356484-7249-5e38-bc5c-adb669fa3297.gif)

また、同じディレクトリ内に途中まで同じ名前のファイルやフォルダが複数ある場合、Tabキーはその共通部分までを補完し、さらに候補を一覧で表示してくれます。

例えば、以下のように dir1、dir2、dir3 が同じディレクトリに存在する場合を見てみましょう。

```shell:shell
root: ~ $ tree
.
├── dir1
├── dir2
└── dir3
```
![tab2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499266/7f5c3540-cabe-a53d-bbcf-e7465eb818e9.gif)

このとき、`vim d` まで入力してから Tabキーを押すと、まず「dir」まで補完され、その後に候補が表示されます。
この機能を使うことにより、効率的にコマンドを入力することができます。

色々細かく書いてしまいましたが、習うより慣れろなところがあるので、とりあえず、Tabを連打する癖をつけましょう笑

#### Ctrl + r　の活用
CLIを使っていると、長いコマンドを何度も入力しなければならない場面が出てきますよね。これを毎回手打ちするのは、正直かなり面倒です。

そんなときに便利なのが、Ctrl + r のショートカットです。
この機能を使うと、過去に実行したコマンドを検索して簡単に呼び出すことができます。
コマンドを再度調べる手間が省けますし、覚えていたとしても入力する手間を省くこともできます。

例えば下記のような複数行にわたって記載されるコマンドも簡単に呼び出すことができます。
(例：AWSのECSコンテナに接続するときのコマンドです）
```shell:shell
aws ecs execute-command --cluster cluster-name \
    --task task-id \
    --container container-name \
    --interactive \
    --command "/bin/sh"
```
![ctrlr.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499266/ed940976-a428-1e06-ec02-d291003cbd2c.gif)

#### historyコマンドの活用
history コマンドは、自分が過去に入力したコマンドの履歴を一覧表示してくれる便利なコマンドです。

先ほど紹介した Ctrl + r と似ていますが、少し用途が異なります。
Ctrl + r はキーワードを使って特定のコマンドを素早く検索できますが、history はコマンドを一覧で確認できるため、「どんなコマンドを使ったか思い出せない」ときに便利です！

![history.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499266/d12a6dbc-8716-a1b8-a069-e834f6a34f4f.gif)

#### |(パイプ）とgrepの活用
|（パイプ）と grep を組み合わせることで、コマンドの出力結果を簡単に絞り込むことができます。

Linuxのコマンドで出力された情報が多すぎて、目的のデータを見つけづらいときにとても便利です。
例えば、先ほど紹介した history コマンドの中から mkdir に関する内容だけを確認したい場合は、次のように入力します。
```shell:shell
history | grep mkdir

```
![スクリーンショット 2024-12-28 23.59.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499266/f10f366a-886d-bdfb-69ca-def8e6c2a3ed.png)

## まとめ
ここでは、LinuxをCLIで操作する際に特に覚えておくと便利なショートカットやコマンドを紹介しました。もちろん、他にも役立つコマンドはたくさんありますが、個人的によく使うと思うものに絞って紹介させていただきました。これらのコマンドを覚えておくと作業がスムーズに進むかと思います。

最初は難しく感じるかもしれませんが、慣れてくるとLinuxでの操作がとても快適になります！よろしかったら参考にしていただけると幸いです。
【Laravel】Collectionを完全に理解する

## 前提知識
LaravelでDBを扱う際の基本的な操作（Eloquent）
https://readouble.com/laravel/11.x/ja/eloquent.html


## はじめに
Eloquentを取り扱うとCollectionが付き纏ってきます。
ちゃんと理解して使ってますか？

自分はCollectionの概念がよく分からず勘で使ってたので、完全に理解するべく使い方を整理してみました。

## 2種類のCollection
Laravelには2種類のCollectionが用意されています。

### `Support\Collection`
>Illuminate\Support\Collection
>https://readouble.com/laravel/11.x/ja/collections.html#method-all

こちらが基本の認識でOK。

配列操作やデータの加工が簡単にできます。

`get()`, `groupBy()`, `where()`等、クエリビルダと同じ名前のメソッドがあるのがややこしいところですが、後述する*基本的な取り扱い*を意識すれば大丈夫かと。

### `Eloquent\Collection`
>Illuminate\Database\Eloquent\Collection
>https://readouble.com/laravel/11.x/ja/eloquent-collections.html

`Support\Collection` を拡張しているのでどちらのメソッドも使えます。

ただ、型指定するときなどに全部こいつを使うと訳分からんことになるので、*Eloquent特有の操作が必要な場合*だけに留めましょう。

## 基本的な取り扱い

### 配列を取り扱う場合
```php
public function supportCollection(): array
{
    $array = ['a' => 1, 'b' => 2, 'c' => 3];

    $collection = collect($array); // コレクション化

    // 何かしら加工（map使うとか）

    return $collection->toArray(); // 配列化して返す
}
```

### クエリビルダを取り扱う場合
```php
public function eloquentCollection(): array
{
    $users = User::limit(5); // クエリビルダでUserモデルを操作

    $collection = $users->get(); // コレクションとして取得

    return $collection->toArray(); // 配列として返す
}
```

## 備考
イントロダクションには次のように書いてある。
>すべての`Collection`メソッドは新しい`Collection`インスタンスを返します。

ただ、呼び出しもとのコレクションを更新するものもあるので注意が必要です。
- `forget()`や`transform()`など

## 感想
おそらく多分完全に理解できた。

調べる前は結構構えてたけど、案外時間かからなかった。

どちらかというとクエリビルダから真面目に調べたほうが良かった気がするので、そっちについても後日同じようにまとめます。
sarコマンドで取得したLinuxのパフォーマンスデータをPythonでグラフ化する②

# はじめに
https://qiita.com/ymiki0001/items/1e0e0a8a1b5858dece9f

上の記事の続編として、グラフにメモリ使用率を追加する。

# 前提
* Jupyter Notebookを使用
* sarで取得したデータはすでにCSV化してあるものとする
* 今回はメモリ使用率をグラフに追加する
* 前回の続きから処理を記述する

# メモリ使用率の計算
df4として、dfからvalue2が%memused（メモリ使用率）となっている行を抜き出す。
```
df4 = df[df['value2'] == "%memused"].reset_index(drop=True)
df4['value3'] = df4.value3.astype(float)
```
```
df4
```
```
	hostname	interval	time	value1	value2	value3
0	test03	1	2024-12-28 13:44:21	-	%memused	9.28
1	test03	1	2024-12-28 13:44:22	-	%memused	9.28
2	test03	1	2024-12-28 13:44:23	-	%memused	9.28
3	test03	1	2024-12-28 13:44:24	-	%memused	9.28
4	test03	1	2024-12-28 13:44:25	-	%memused	9.28
...	...	...	...	...	...	...
295	test03	1	2024-12-28 13:49:16	-	%memused	9.23
296	test03	1	2024-12-28 13:49:17	-	%memused	9.23
297	test03	1	2024-12-28 13:49:18	-	%memused	9.23
298	test03	1	2024-12-28 13:49:19	-	%memused	9.24
299	test03	1	2024-12-28 13:49:20	-	%memused	9.24
300 rows × 6 columns
```
value3の列がメモリ使用率となる。
df3をdf5にコピーし、MEM Usageとしてdf4のvalue3の値を追加する。
```
df5=df3
df5['MEM Usage'] = df4['value3']
```
```
df5
```
```

hostname	interval	time	value1	value2	value3	CPU Usage	time2	MEM Usage
0	test03	1	2024-12-28 13:44:21	all	%idle	99.01	0.99	13:44:21	9.28
1	test03	1	2024-12-28 13:44:22	all	%idle	93.47	6.53	13:44:22	9.28
2	test03	1	2024-12-28 13:44:23	all	%idle	93.07	6.93	13:44:23	9.28
3	test03	1	2024-12-28 13:44:24	all	%idle	92.96	7.04	13:44:24	9.28
4	test03	1	2024-12-28 13:44:25	all	%idle	92.12	7.88	13:44:25	9.28
...	...	...	...	...	...	...	...	...	...
295	test03	1	2024-12-28 13:49:16	all	%idle	91.63	8.37	13:49:16	9.23
296	test03	1	2024-12-28 13:49:17	all	%idle	92.61	7.39	13:49:17	9.23
297	test03	1	2024-12-28 13:49:18	all	%idle	93.00	7.00	13:49:18	9.23
298	test03	1	2024-12-28 13:49:19	all	%idle	93.00	7.00	13:49:19	9.24
299	test03	1	2024-12-28 13:49:20	all	%idle	93.00	7.00	13:49:20	9.24
300 rows × 9 columns
```
これで、時刻（time2）、CPU使用率（CPU Usage）、メモリ使用率（MEM Usage）の準備ができた。

# グラフ描画
time2、CPU Usage、MEM Usageを使用してグラフを描画する。
```
plt.rcParams['figure.figsize'] = (16.0, 3.0)
df5.plot(x='time2', y=['CPU Usage', 'MEM Usage'])
plt.xlabel('')
plt.savefig("test-sar002.png")
```

出力されたグラフは下のようになる。

![test-sar002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662088/f00e736e-ad16-5c9e-6cab-d01c23af4d10.png)

以上。
MyBatisでSELECTする

# はじめに
現場にてデータベースの操作はMyBatisGeneratorで自動生成したものを使用したが、SELECTなどは処理にあわせて作成したため、備忘録としてまとめます。

# 変数を渡して検索
Mapperクラスにて明記している引数は`#{}`を使いバインドさせます。
`resultType`に取得したデータを格納するEntityなどのパスを設定します。
```java
public interface KeiyakuMapper {
    List<KeiyakuEntity> SelectKeiyaku(String keiyakuNo);
}
```

```xml
<select id="SelectKeiyaku"
    resultType="jp.co.entity.KeiyakuEntity">
    SELECT *
      FROM keiyaku
     WHERE keiyaku_no = #{keiyakuNo} 
</select>
```

# 部分一致の検索
部分一致の検索にはワイルドカードの`%`を使います。
`CONCAT`にて`#{}`の部分と結合させます。
```java
public interface BushoMapper {
    List<BushoEntity> SelectBusho(String bushoId);
}
```

```xml
<select id="SelectBusho"
    resultType="jp.co.entity.BushoEntity">
    SELECT *
      FROM Busho
     WHERE busho_id = LIKE CONCAT(#{bushoId}, '%')
</select>
```

# リストの要素を検索
画面にて複数のチェックボックスが選択されたときなどに必要になった処理です。
引数が２つ以上あるのでアノテーションの`@Param`を引数に設定します。
`foreach`を使い`IN句`に渡すパラメーターをループさせます。
```java
public interface KeiyakuMapper {
    List<KeiyakuEntity> SelectKeiyakuIn(@Param("keiyakuNo")String keiyakuNo, @Param("statusList") List<String> statusList);
}
```

```xml
<select id="SelectKeiyakuIn"
    resultType="jp.co.entity.KeiyakuEntity">
    SELECT *
      FROM keiyaku
     WHERE keiyaku_no = #{keiyakuNo}
       AND status IN
     <foreach item="status" collection="statusList" open="(" separator="," close=")">
        #{status}
     </foreach>
</select>
```

# 条件分岐
引数のパラメーターがnullや空白が渡されたときはWHERE句には設定しないなどの処理が必要な場合は、`if`を使えば条件分岐できます。

```java
public interface KeiyakuMapper {
    List<KeiyakuEntity> SelectKeiyakuIf(String keiyakuNo);
}
```

```xml
<select id="SelectKeiyakuIn"
    resultType="jp.co.entity.KeiyakuEntity">
    SELECT *
      FROM keiyaku
     WHERE 1 = 1
    <if test = "keiyakuNo != null and keiyakuNo != ''">
        keiyaku_no = #{keiyakuNo}
    </if>
</select>
```

# 参考にした記事

https://qiita.com/RinTenma/items/a9d092f556b4f0fc5307
【Git】stashに名前をつける方法

以下のコマンドを実行するとstashに任意の名前をつけることができます。

```terminal
git stash push -m "sample"
```

```terminal
$ git stash list
stash@{0}: On main: sample
```

変更を適用するには以下のようにします。

```terminal
$ git stash list
stash@{0}: On main: sample
$ git stash apply stash@{0}
```
[Microsoft] Windows SDDL (Security Descriptor Definition Language) 文字列を解読する

# この記事はなに？

Windows の SDDL (Security Descriptor Definition Language) を解読します。

[Lacさんの記事](https://devblog.lac.co.jp/entry/20231113) の焼き直しです。

https://devblog.lac.co.jp/entry/20231113


# SDDL文字列の構造

SDDLは、いくつかの決められたプレフィックスを持つ文字列を、区切りなしに並べたひと続きの文字列です。

```text:SDDL文字列の例
O:BAG:SYD:P(A;OICI;FA;;;SY)(A;OICI;FA;;;BA)(A;OICI;FA;;;LA)
```

癖強いっすね :sweat_smile:

## SDDLのプレフィックス

プレフィックスには、以下の4つがあります。

| プレフィックス | 意味 |
|:-:|:--|
| O:  | Owner (所有者)  |
| G:  | Group (プライマリグループ)  |
| D:  | Discretionary Access Control List (DACL)  |
| S:  | System Access Control List  |

:::note
**S:** は、一般ユーザーには関係ないらしいので、ここでは無視です。
:::

先の例を分解すると、こうなります。

| 項目 | 値 |
|:--|:--|
| 所有者 (O:)  | BA  |
| プライマリグループ (G:)  | SY  |
| DACL (D:)  | P(A;OICI;FA;;;SY)(A;OICI;FA;;;BA)(A;OICI;FA;;;LA)  |

## 所有者やプライマリグループを表す文字列

所有者やプライマリグループは、SIDか、**BA** や **SY** のような、あらかじめ決められている文字列だそうです。

https://learn.microsoft.com/en-us/windows/win32/secauthz/sid-strings

先の例は、このような意味です。

| 文字列 | 意味 |
|:-:|:--|
| BA  | Built-in administrators.  |
| SY  | Local system.   |


# DACLの構造

プレフィックス **D:** で始まる DACL の構造です。

```text
フラグ(ACE文字列1)(ACE文字列2)...(ACE文字列n)
```

フラグで始まり、カッコで囲まれたACE文字列が羅列されます。

先の例を分解するとこうなります。

| 項目 | 値 |
|:--|:--|
| フラグ  | P  |
| ACE文字列1 | A;OICI;FA;;;SY |
| ACE文字列2 | A;OICI;FA;;;BA |
| ACE文字列3 | A;OICI;FA;;;LA |


## DACLのフラグ

以下の4つのうちのひとつ、あるいは複数を区切りなしに並べた文字列です。

| フラグ | 意味 |
|:-:|:--|
| P  | SE_DACL_PROTECTED フラグがセットされている  |
| AR  | SE_DACL_AUTO_INHERIT_REQ フラグがセットされている  |
| AI  | SE_DACL_AUTO_INHERITED フラグがセットされている |
| NO_ACCESS_CONTROL  | ACLがNull  |

意味わかりませんが、重要ではないらしいので、スルーします。

# ACE文字列の構造

ACE文字列は、以下の項目をセミコロンで区切って並べた文字列です（その意味は後述）。

1. ACEタイプ
1. ACEフラグ
1. 権限
1. オブジェクトのGUID
1. 継承オブジェクトのGUID
1. アカウントのSID

先の例を分解すると、こうなります。

| 項目 | 値 |
|:--|:--|
| ACEタイプ  | A  |
| ACEフラグ  | OI と CI  |
| 権限  | FA  |
| オブジェクトのGUID  | （なし）  |
| 継承オブジェクトのGUID  | （なし）  |
| アカウントのSID | SY|


## ACEタイプ

あらかじめ決まっている文字列です。**A** が許可、**D** が拒否です。他にもいろいろあります。

https://learn.microsoft.com/en-us/windows/win32/secauthz/ace-strings#fields

先の例ですと、**A** なので許可を意味します。

## ACEフラグ

ひとつまたは複数のフラグを区切りなしに並べた文字列です。そのACEがどのように扱われるのかを決めます。

ファイルシステムでよく使うのはこれくらいでしょうか。

| フラグ | 意味 |
|:-:|:--|
| CI  | サブフォルダのみに影響  |
| OI  | ファイルのみに影響  |
| IO  | フォルダ自身には影響しない  |
| NP  | サブフォルダに継承させない |

先の例ですと、**OICI** なので、フォルダ自身、サブフォルダ、ファイルに影響します。

## 権限

**0x** で始まる16進数か、あらかじめ決められている文字列の羅列になります。

## オブジェクトのGUID

ある特定のACE構造体 （Win32 プログラムで使うやつ）の **ObjectType** メンバーに格納する値です。

たぶん、どんなACEを記述するかによって、値の意味が変わるのだと思われます。

## 継承オブジェクトのGUID

ある特定のACE構造体 （Win32 プログラムで使うやつ）の **InheritedObjectType** メンバーに格納する値です。

たぶん、どんなACEを記述するかによって、値の意味が変わるのだと思われます。


## アカウントのSID

このACEが適用されるアカウントのSIDです。




# 参考リンクまとめ

記事内に書いたリンク先のまとめです。

- SDDLの説明入り口 https://learn.microsoft.com/en-us/windows/win32/secauthz/security-descriptor-definition-language
- SID文字列 https://learn.microsoft.com/en-us/windows/win32/secauthz/sid-strings
- ACE文字列 https://learn.microsoft.com/en-us/windows/win32/secauthz/ace-strings
スプレッドシートにカスタムメニューを作成してGAS実行を効率化する方法

## はじめに

:::note info
※本記事は、GAS(Google Apps Script)やバッチファイルを使って、バックオフィス周りの業務効率化、業務改善を実施している非エンジニアによる記事です。
:::

作成したGASを実行する際、スクリプトエディタから実行するのは少々手間がかかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628613/a7fdb994-3231-af03-45a4-d6b6389c1e96.png)

この記事では、カスタムメニューをスプレッドシート上に作成し、シートからワンクリックでスクリプト実行できる方法を紹介します。

---

## 実践するスクリプトの概要
1. Googleスプレッドシートにカスタムメニューを作成。
2. 実行したいスクリプトをメニューから実行可能にする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628613/0b419906-5589-98a0-af6c-29ad6474dbe7.png)

---

## コードの全体像
メニューから呼び出すGASは、[こちらの記事](https://qiita.com/yuto-h/items/f71773e6967295c39fd9)で紹介したものにします。
※作成したメニューから**「PDFを取得してURL化する」**という処理を実行できる構成になっています。

#### コード
```javascript
// メニューを作成
function onOpen() {
  var ui = SpreadsheetApp.getUi();  // UIを取得する
  var menu = ui.createMenu("スクリプト実行"); // カスタムメニューを作成
  menu.addItem("PDFを取得してURL化する", "getPdfFromGmail"); // メニューアイテムを追加
  menu.addToUi(); // メニューをUIに追加
}
```

---

## スクリプトの機能解説

### 1. **カスタムメニューを作成する仕組み**
- **`onOpen`関数**:
  Googleスプレッドシートを開いた際に実行されるトリガーです。メニューの作成はこの関数内で行います。
  <br>
  
- **`SpreadsheetApp.getUi`**:
  ユーザーインターフェイスを取得するメソッドです。このオブジェクトを通じて、メニューバーの操作が可能になります。
  <br>
  
- **`menu.addItem`**:
  メニューにアイテム（選択肢）を追加します。第一引数がメニューに表示される名前、第二引数が実行される関数名です。
  <br>
  
- **`menu.addToUi`**:
  作成したメニューをスプレッドシートのメニューバーに追加します。

### 2. **スクリプトを実行する仕組み**
`getPdfFromGmail`関数には、PDF取得や処理を行うスクリプトの実装を記述します。
この関数をメニューから実行可能にすることで、スプレッドシート上で簡単に処理を開始できます。

---

## 実行手順

1. **Googleスプレッドシートを開く**
   対象のスプレッドシートを用意します。
   <br>

2. **Google Apps Scriptを開く**
   メニューバーの`拡張機能` → `Apps Script`を選択し、エディタを開きます。
   <br>

3. **スクリプトをコピー＆ペースト**
   上記のコードをエディタに貼り付け、保存します。
   <br>

4. **スプレッドシートをリロード**
   スプレッドシートを再読み込みすると、メニューバーに``スクリプト実行``が表示されます。
   
   ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628613/b84e0b4f-a49d-4d26-c082-34a1b52b337b.png)
   <br>


5. **メニューからスクリプトを実行**
   - ``PDFを取得してURL化する``をクリックしてスクリプトを実行します。
   
   ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628613/9d9d5ba0-9352-0986-6557-41d680b955b0.png)

---

## おわりに

いかがでしたでしょうか。

トリガーを設定せず、手動で定型的に実行するスクリプトに関しては、このようにメニューから実行できるようにしておくと、とても便利です◎
※**複数人が実行するGAS**であれば、なおさら良いですね！

ご活用いただければ幸いです！
sarコマンドで取得したLinuxのパフォーマンスデータをPythonでグラフ化する①

# はじめに
https://qiita.com/ymiki0001/items/d5fe7d06c83d5f46957e

上の記事でCSV化したLinuxのパフォーマンスデータをPythonでグラフ化する。

# 前提
* Jupyter Notebookを使用
* sarで取得したデータはすでにCSV化してあるものとする
* 今回はCPU使用率をグラフ化する

# 必要なモジュールのインポート
今回使用するモジュールをインポートする。
なお、以降は全てJupyterNotebook上で実行している。

```
import pandas as pd
import matplotlib 
import matplotlib.pyplot as plt
```

# ファイルの読み込み
データフレームとしてCSVファイルを読み込む。
```
df = pd.read_csv('test-sar001.csv', names=['hostname', 'interval', 'time', 'value1', 'value2', 'value3'])
```

# CPU使用率の計算
CPU使用率の計算のため、value1がCPU全体を示すallになっておりvalue2がCPUのidleの割合を示す%idleになっている行をdfから抜き出す。
まず、df2として、value2が%idleとなっている行を抜き出す。
さらにdf3として、value1がallになっている行を抜き出す。
```
df2 = df[df['value2'] == "%idle"]
df3 = df2[df2['value1'] == "all"].reset_index(drop=True)
```
CPU Usageとして、100からvalue3を引いた値をセットする。（100から%idleを引いた値を使用率としている）
```
df3['CPU Usage'] = 100.0 - df3['value3']
```


df3を表示すると以下のようになっている。
```
df3
```
```
	hostname	interval	time	value1	value2	value3	CPU Usage
0	test03	1	2024-12-28 13:44:21	all	%idle	99.01	0.99
1	test03	1	2024-12-28 13:44:22	all	%idle	93.47	6.53
2	test03	1	2024-12-28 13:44:23	all	%idle	93.07	6.93
3	test03	1	2024-12-28 13:44:24	all	%idle	92.96	7.04
4	test03	1	2024-12-28 13:44:25	all	%idle	92.12	7.88
...	...	...	...	...	...	...	...
295	test03	1	2024-12-28 13:49:16	all	%idle	91.63	8.37
296	test03	1	2024-12-28 13:49:17	all	%idle	92.61	7.39
297	test03	1	2024-12-28 13:49:18	all	%idle	93.00	7.00
298	test03	1	2024-12-28 13:49:19	all	%idle	93.00	7.00
299	test03	1	2024-12-28 13:49:20	all	%idle	93.00	7.00
300 rows × 7 columns
```

timeから時刻のみ取り出したものをtime2として追加する。
```
df3['time2'] = df5['time'].str[-8:]
```
```
df3
```
```
	hostname	interval	time	value1	value2	value3	CPU Usage	time2
0	test03	1	2024-12-28 13:44:21	all	%idle	99.01	0.99	13:44:21
1	test03	1	2024-12-28 13:44:22	all	%idle	93.47	6.53	13:44:22
2	test03	1	2024-12-28 13:44:23	all	%idle	93.07	6.93	13:44:23
3	test03	1	2024-12-28 13:44:24	all	%idle	92.96	7.04	13:44:24
4	test03	1	2024-12-28 13:44:25	all	%idle	92.12	7.88	13:44:25
...	...	...	...	...	...	...	...	...
295	test03	1	2024-12-28 13:49:16	all	%idle	91.63	8.37	13:49:16
296	test03	1	2024-12-28 13:49:17	all	%idle	92.61	7.39	13:49:17
297	test03	1	2024-12-28 13:49:18	all	%idle	93.00	7.00	13:49:18
298	test03	1	2024-12-28 13:49:19	all	%idle	93.00	7.00	13:49:19
299	test03	1	2024-12-28 13:49:20	all	%idle	93.00	7.00	13:49:20
300 rows × 8 columns
```

これで準備ができたので、matplotlibを使用してグラフを描画する。
plt.savefigは作成したグラフをpngとして描き出すために指定している。
```
plt.rcParams['figure.figsize'] = (16.0, 3.0)
df3.plot(x='time2', y=['CPU Usage'])
plt.xlabel('')
plt.savefig("test-csv001.png")
```
出力されたグラフは下のようになる。
![test-csv001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662088/3f5acf52-8450-d6a1-3f74-3d4a9e895977.png)



以上。
Adobe Substance 3D Painterでpytestを実行する方法

## 環境
* Windows
* Adobe Substance 3D Painter 10.1.2 
* pytest 8.3.4

## 前提

Substance 3D PainterはコマンドラインからPythonを実行することが出来ないためPython Console (REPL) からpytestを実行する手段を考えます。

## 方法

Python Consoleから下記のようなコードで実行出来ます。

```
>>> import pytest
>>> pytest.main(args=["file_or_dir", "-p", "no:faulthandler"])
```

実行結果参考
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3965005/672f1ac5-da13-6cb3-e18c-c2a7e436eaed.jpeg">

## 説明

### 関数

Python Consoleから実行するためにまずpytest.exeが呼び出している関数を確認します。

エントリーポイント (`__main__.py`) を見ると
```
if __name__ == "__main__":
    raise SystemExit(pytest.console_main())
```
となっているので次に `pytest.console_main()` を確認します。

`pytest.console.main()` は `pytest/__init__.py` から `_pytest/config/__init__.py` の console_main関数であることがわかります。

さらに `_pytest/config/__init__.py` の console_main関数を確認すると、コードとdocstringから
`_pytest/config/__init__.py` のmain関数を利用すればよいと判断できます。

また `_pytest/config/__init__.py` のmain関数については `pytest/__init__.py` の `__all__` の定義でパッケージからimportされるため、最終的に

```
>>> pytest.main(args=None, plugins=None)
```
を実行すればよいということがわかります。

### 引数

```_pytest/config/__init__.py``` のmain関数のdocstringを読むと `args` にpytestのコマンドライン引数をリスト形式で渡せばよいことがわかります。

### faulthandlerの無効化

Substance 3D Painterでは `sys.__stderr__` が `None` であるためfaulthalderを無効化せずpytestを実行すると `INTERNALERROR` が発生します。

<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3965005/1e3ffbc2-49be-c5eb-15dc-bb2772d1f5b7.jpeg">

そのためfaulthandlerを無効化 (`-p no:faulthandler`) します。
HHKBっていいぞお

## HHKBっていいぞお
みなさんこんにちは，宮治研究室カレンダー大遅刻のmahoです！
今回は，先日購入したHHKBをおすすめしようっていう記事です！
ぜひ記事を読んで，皆様ポチっちゃってください！

### HHKBとはなんぞや
HHKBってなんぞやって方はまず公式サイトで見た目だけ見ちゃってくださいな

HHKB公式サイトはこちら↓
https://happyhackingkb.com/jp/

まあHHKBを一言でいえば，最高級キーボードです．
値段も最高級です，はい，￥36,000くらいです

### HHKBとの出会い
私の初めてのHHKBとの出会いは，長期インターンの先輩学生エンジニア達が使っていたことでした．
見た目がスタイリッシュでかっこいーなーって思い，
「そのキーボード使いやすいですか？」と聞いたら
「ちょっと触ってみますか？」と触らせてもらいました．
触り心地はふかふかして，気持ちいい感触でしたね．
その時の私は，キーボードはmacbookのキーボード，モニターなしの環境がデフォルトだったので，お金を出してキーボードを買うなんて，アホらしいとさえ思ってました．
お値段聞いたところ，まあ，いいお値段！？
エンジニアってなんて恐ろしい金銭感覚！

**私は将来絶対こんなお金の使い方なんてしないだろうなあ，なんて思ったわけです(フラグ1)．**

先輩Kさんも，HHKBユーザーでした．
その先輩は週2出社で．いちいち，HHKBを買った時についてくる箱に入れて会社に持ってきて，持って帰っていました．
HHKBは大体お弁当箱2つくらいの大きさですが，この人は箱に入れて，持ち歩いている！？
しかもケースとかじゃなく，買った時の箱．
**私にとっては，ipadを持ち歩くのに，買った時の箱に入れて持ち歩いてる，そんな滑稽な姿に見えました（フラグ2）．**

また，先輩Nさんも，HHKBユーザーでした．
Nさんは，週５出社なので，金曜日以外はオフィスにHHKBを置いて帰ります．
その時に，木製の蓋をして帰るんですね．
そんな専用の蓋があるんだと思ってました．
蓋は適当に買って，DIYでもしたのかななんて思ってましたら，HHKBが公式で出している，パームレストだそう．
公式の，木の，蓋．
それが本体と同じ値段（￥34,000）．
アホか，この人は．と．
**私はそんなものは絶対に欲しくならないだろう(フラグ3)**
なんて思ってました．

### HHKBを買うきっかけ
卒業論文を執筆している際に，これは何かモチベーションにつながる道具が欲しいなあと思って，HHKBが思いあたりました．
様々なレビューを見ながら，数日購入を悩みましたが，論文の疲れからか，ええい買ってしまえ！と半ば衝動で購入しました．
私は公式サイトから購入しましたが，午後注文したにも関わらず，翌日午前中に届いたのは驚きでしたね．
早速，その日研究室にHHKBを持って行きました．
**もちろん，買ったその箱で．(フラグ回収)**

私が購入したモデルは，Professional HYBRID Type-S 雪です．
もちろん，英字配列で．
Bluetooth接続ができること，マウスは将来トラックボールの購入を予定していてマジックパッド？の機能は必要ないことからモデルを選びました．

## HHKBを使ってみてのメリット
一言でいえば，もちろん最高です．
ふかふかした打鍵感が大好きですね．
あとは刻印がはっきりしていないことで，半強制的にタッチタイピングになるので，文字入力のスピードが上がったと思います．
あとは，英字配列は本当にいいです．
今までは，日本語配列しか存在を知りませんでしたが，英字配列を選びました．
矢印キー（←↑→↓）がないことをデメリットと挙げる意見もありますが，むしろ両手がホームポジションから大きく動くことなく矢印キーを打てることはメリットだと感じています．
gitコマンドを打つとき，英字配列の合理性を実感しました．

## HHKBを使ってみてのデメリット
メリットがあれば．デメリットがある，ということで．
デメリットは，これからはHHKB無しでは生活できない，ということです．
つまり，HHKBを持ち運ぶ，もしくは複数台の所有がマストになります（お財布大打撃）．
この文章は諸事情でmacの純正キーボードで打っていますが，HHKBが欲しくてたまりません．

## さあ，次はみなさんが使ってみる番です．
あとは，このリンクをクリックして，一緒にHHKB信者になりましょう．
（リンクは，雪ではなく白ですね）
https://amzn.to/3PdcNxY

私は今，散々馬鹿にしていた木製のパームレスト兼キーボードルーフが欲しくなっています．
それでは，良いお年を．
2024年の資格取得実績をまとめてみた

# はじめに
2024年度もあと少しで終わりということで、今年取得した資格についてまとめてみました。

# 2024年 資格取得実績
2024年度に取得した資格を整理すると、合計で7つの資格を取得できておりました。
思った以上に数が多くなっており、少し驚きました。
この結果となった要因としては、AWS-SAPの取得とANGEL Dojoへの参加が大きく、そこを起点として継続して試験を受けるモチベーションを維持できたと思います。また、AWS試験の間に1つだけあるCKAについても１発でとれてホッとしました。

|No|資格名|受験日|合否|
|---|---|---|---|
|1|AWS Certified Solutions Architect – Professional (1回目)|2024-03-20|×|
||AWS Certified Solutions Architect – Professional (2回目)|2024-06-26|×|
||AWS Certified Solutions Architect – Professional (3回目)|2024-07-15|⚪︎|
|2|AWS Certified Security - Specialty|2024-08-18|⚪︎|
|3|AWS Certified Developer - Associate|2024-09-02|⚪︎|
|4|Certified Kubernetes Administrator|2024-10-13|⚪︎|
|5|AWS Certified SysOps Administrator - Associate|2024-10-28|⚪︎|
|6|AWS Certified Data Engineer - Associate|2024-11-17|⚪︎|
|7|AWS Certified AI Practitioner|2024-12-09|⚪︎|

# おわりに
今年受験した資格について振り返ってみました。AWSについては順調に取得を進められており、AllCertまではあと5つとなります。やや厳し目ですが、狙えなくはない状況ですので引き続き資格取得を進めていきます。また勉強法についてもどこかでまとめられればと思います。
40代から始めるAWS Certified AI Practitioner (AIF-C01)認定試験備忘録

## この記事の目的
本日（2024年12月28日）にAWS Certified AI Practitioner（AIF-C01）認定試験を合格したので、その備忘録として作成しました。
試験勉強の方法も今まで受けた基本情報などから大きく変えたので、そのへんも含めて書いていこうと思います。

## 受験動機
業務では実装の補助にAmazon Q Developerや各種Chatbotを使う程度だったが、いい機会なので試験勉強を通じてAWSの生成AI関連サービスについて勉強してみようと思って調べたら、来年（2025年）2月15日までに合格したらアーリーアドプターバッジ貰えることを知ったから慌てて受験した。（めちゃくちゃ不純）
本当は業務の合間に来年1年くらいかけてゆるっと勉強するつもりだった。

まぁ、実際に業務で生成AI関連のサービスを作るかどうかは置いておいて、利用する側として全く関わらないということもないと思うので、勉強しといて損はない分野ですしね。

## 受験者のスキル
* 一応本職はサーバーサイドエンジニア~~ただ直近の案件では人員構成の関係でインフラ周りをメインにやってたので同僚にもインフラエンジニアと思われていた~~
* AWS自体は数年業務で利用しており、DAU数万のサービスのアーキテクチャ設計、構築程度の経験はあるため、そこについての懸念はあまり感じてはいなかった
* 生成AIについては上記の通り、コーディングの補助程度にしか利用してなかったため、ほぼ全く知らない状況からのスタート

## 試験準備
### 期間
11月末からの1ヶ月弱、1日30分～1時間程度

### 勉強方法
4月にAWS Certified Cloud Practitioner (CLF-C02) 試験を受験した際、合格はしたのですが、今までのように勉強本を買って何度も読みながら問題を解いて勉強していくというスタイルに、個人的に限界を感じていたので、今回は少しスタイルを変えてUdemyで試験対策用の講座を購入し、スキマ時間にいつどこでも勉強が出来るよう、スマホ一つで試験勉強が完結するスタイルで今回は望みました。
（ちょうど試験申し込みのタイミングでUdemyがブラックフライデーセールを行っていたというのもありましたが）

購入後、新しい試験ということもあり、この1ヶ月弱の勉強期間の間にどちらの講座も何度かアップデートされていたのは、個人的には心強く感じました。

[【最新】AWS認定AIプラクティショナー試験突破講座＋模擬試験２回分付き！](https://www.udemy.com/course/aws-ai-practitioner/)
最初の2週間はこちらの講座の動画を1日30分くらいを目処に、
キリがいいところまで目を通して、分からない言葉が出てきたら後でググったり、
実際にAWSの環境を触って確認していくという形で進め、

[AIF-C01 / AWS Certified AI Practitioner 模擬試験（4回分）＋補足問題](https://www.udemy.com/course/aws-certified-ai-practitioner-certification-55-4/)
残りの2週間はひたすらこっちの模試試験の問題を解いて、更に理解を深めていく形で進めました。
本番試験と比較して、出題内容のフォロー率が6～7割、よくて8割程度かなという感じだったので、この模擬試験の正解率が7割ギリギリくらいだとちょっと厳しいのかなと個人的には思います。

## 試験当日
受験申し込みの際に全て手続きは済んでると思うので、当日は受付で提示する身分証明書2つを忘れなければ特に問題はないと思います。
あと試験結果通知のメールがいつまで経ってもこなくて（実はこの記事を書いた時点でもまだ来ていない）、Credlyのバッジ獲得したよ！メールで壮大なネタバレを食らったのちょっと笑った。

## 所感
まぁ実際受けてみると、結構ギリギリではありましたが、無事に合格することが出来ました。
試験結果のスコアパフォーマンスを見た限りだと、勉強を始めたばかりのときは右も左もわからないことばかりだった「AIとMLの基礎」「生成AIの基礎」「基盤モデルの応用」あたりでは結構点が取れているようなので、この1ヶ月間の勉強の成果はある程度出せたのではと思います。

後はせっかくなので、今回勉強したことを通じて、コーディング作業の効率化だけでなく、ビジネス的な部分での、業務改善や機能開発の提案とかも出来ないかとか、ちょっと色々模索していこうかな、と。
【Jest × Chakra UI】Property 'children' does not exist on typeの解決方法

# はじめに
Chakra UIがv3にアップデートされた後、発生した型エラーについて解決方法を紹介します。

:::note warn
***この記事は<font color="Red">個人的なアウトプット</font>を目的として作成したものです。そのため、誤った情報や不足している内容が含まれている可能性があります。もし間違いや気になる点がございましたら、ぜひご指摘いただけますと幸いです***。
:::

# 問題
`Chakra UI`の`FileUploadDropzone`を使用している際、`Jest`でテストを実行すると以下のエラーが発生しました：

```bash
 src/components/ui/file-button.tsx:43:11 - error TS2339: Property 'children' does not exist on type 'FileUploadDropzoneProps'.
 const { children, label, description, ...rest } = props
```
このエラーの原因は、`FileUploadDropzoneProps`に`children`プロパティが定義されていないためです。`children`を含む型を追加しなければ、このプロパティを解釈できずにエラーが発生します。
# 解決方法
以下のように型定義を修正し、`children`プロパティを追加しました
```react
export interface FileUploadDropzoneProps extends ChakraFileUpload.DropzoneProps {
  label: React.ReactNode;
  description?: React.ReactNode;
  children?: React.ReactNode;//childrenの型設定を追加
}
```
これにより、childrenが含まれる場合でも型エラーが発生しなくなりました。

# 終わりに
Chakra UIのアップデートやライブラリの変更に伴い、型エラーや予期せぬ問題が発生することはよくあります。今回の経験を通じて、型定義の重要性を改めて実感しました。

# 参考

『【Chakra UI v3 × jest】テスト時のDialogContentの型エラーの解消方法（Type '{ children: Element[]; }' has no properties in common with type 'IntrinsicAttributes & DialogContentProps & RefAttributes<HTMLDivElement>'.）』Qiita

https://qiita.com/ritsu21ctws/items/ebf7c9c2e3f082c23ec1

https://stackoverflow.com/questions/59106742/typescript-error-property-children-does-not-exist-on-type-reactnode
ABC386をPythonで（A～E）

AtCoder Beginner Contest 386の解答等の速報的まとめ

https://atcoder.jp/contests/abc386



# A問題
https://atcoder.jp/contests/abc386/tasks/abc386_a

2種類渡されているとき、条件に当てはまる
```python:A
print("Yes" if len(set(input().split())) == 2 else "No")
```

# B問題
https://atcoder.jp/contests/abc386/tasks/abc386_b

00を0に置換して文字列を数える
```python:B
s = input().replace("00", "0")
print(len(s))
```

# C問題
https://atcoder.jp/contests/abc386/tasks/abc386_c

まったく同じか変更する1箇所以外同じであるかを調べる
```python:C
def same_string_count(s, t):
    res = 0
    for s_i, t_i in zip(s, t):
        if s_i == t_i:
            res += 1
        else:
            break
    return res


k = int(input())
s = input()
t = input()

if s == t:
    exit(print("Yes"))
if abs(len(s) - len(t)) >= 2:
    exit(print("No"))

a = same_string_count(s, t)
b = same_string_count(s[::-1], t[::-1])

if (len(s) == len(t) and len(s) - a - b <= 1) or (len(s) != len(t) and a + b >= min(len(s), len(t))):
    print("Yes")
else:
    print("No")
```

# D問題
https://atcoder.jp/contests/abc386/tasks/abc386_d

縦横それぞれで
インデックス順に、白に塗らないといけない場所と黒に塗らないといけない場所の境界が次第に小さくなればいい
```python:D
def check(d):
    last_white = n + 1
    for key in sorted(d.keys()):
        white_flg = False
        white_ind = n + 1
        black_ind = -1
        lst = sorted(d[key])
        for ind, c in lst:
            if c == "W":
                white_flg = True
                white_ind = min(white_ind, ind)
            else:
                if white_flg:
                    return False
                black_ind = ind
        if black_ind >= last_white:
            return False
        last_white = min(last_white, white_ind)
    return True


n, m = map(int, input().split())

x = dict()
y = dict()

for _ in range(m):
    x_i, y_i, c_i = input().split()
    x_i = int(x_i)
    y_i = int(y_i)
    if x_i not in x:
        x[x_i] = list()
    if y_i not in y:
        y[y_i] = list()
    x[int(x_i)].append((int(y_i), c_i))
    y[int(y_i)].append((int(x_i), c_i))

print("Yes" if check(x) and check(y) else "No")
```

# E問題
https://atcoder.jp/contests/abc386/tasks/abc386_e

combinationsで全組み合わせを出力してXORの最大値を求める
```python:E
from itertools import combinations

n, k = map(int, input().split())
a = list(map(int, input().split()))
default = 0
if k * 2 > n:
    for a_i in a:
        default ^= a_i
    k = n - k

ans = 0
for p in combinations(a, k):
    ans_i = default
    for p_i in p:
        ans_i ^= p_i
    ans = max(ans, ans_i)

print(ans)
```
オープン化のススメ: 給料すらも全部見える化しちゃえば、ゴーストエンジニアだっていなくなるんじゃないの？

# 背景

会社で Teams を使っているが、昔からの悩みが・・

- 多くの人の好み: `チャット` で業務。`チャネル` は必要最低限
- 自分の好み: `チャネル` で業務。チャットは私的なやり取り

事業本部制の悪影響で、仲間意識よりも、競争相手として情報を遮蔽しがちな感覚
その文化の影響で、`Taker` >> `Giver` になってるんじゃないのかな、と

---

そんな折、業務で関係を持った人たちが、何度伝えてもチャットを飛ばしてくるので、相手の立場に立って？利点を説明することで変わってもらいたいなと思い投稿した内容をちょっとだけ再編してみた記録

オープン化でゴーストエンジニア問題も解決しないかなぁ・・なんて :thinking: 

https://www.businessinsider.jp/post-297806

# 具体的な内容: 社内で殴り書いたやつを再整理 :p

なぜ、**オープン化** が好きなのか？

1. 効率の向上: 重複作業を減らし、効率的に業務を進められる
1. イノベーションの促進: 多様な視点から新しい発想が生まれやすくなる
1. 信頼関係の構築: 透明性が信頼関係を強化します
1. 迅速な問題解決: 情報共有により迅速な対応が可能です
1. 性善説の進行: 「視られる」意識が、良い行動を促す 

Working Out Loud（WOL）のアプローチを取り入れることで、オープン化の効果をさらに高めることができます。WOLとは、自分の仕事の進捗や考えを積極的に共有し、フィードバックを受け入れる方法です。


## Microsoft 365 におけるオープン化の実践例
使うツールとしては、
- Teams
- Azure DevOps Wiki + Repos
    - 非エンジニアであっても、ドキュメントを git 管理する利点を感じてほしいなぁなんて。markdown + marp で Power Point/PDF 吐くのもいいですしね :laughing: 
    
### 業務は、基本 Teams Channels 
- 質問の共有
質問を共有することで、他の人の知見を得られるかもしれません。反応がない場合でも、自分で調べる際の手助けになります。また、質問を書いているうちに、調べていないことや前提があやふやなことに気づき、自己解決しやすくなります。

- 作業の共有
作業記録を残すことで、認識齟齬を埋めやすくなり、他の人が気付きを得やすくなります。また、もっと良いやり方を教えてもらうこともできます。

- 会議はチャネルに紐付け
ばらばらの会議で、会議での展開資料や、チャットの記録が電子の彼方に消えていってしまうことを防ぐ

- 体系的なまとめの記録
出来れば、wiki なんかに、チャネルでのやり取りを体系的にまとめるのが大事。とはいえ、検索があればだいたいは何とかなるので、Copilot を信じて待つのもありかも

### 個人的なことは、Chat でも
個人的な雑談や、裏工作は個人チャットも必要かもですね :laughing: 


# 補足：ジョハリの窓なら、全開がオススメ

|-|**自分は** 知っている|**自分は** 知らない|
|-|-|-|
|**他人は** 知っている|自分も他人も、知っている|自分だけが気付いていない|
|**他人は** 知らない|他人には見せていない一面|自他ともに気付いてない内面|

有名なジョハリの窓。

自分がこれを知ったときに考えたこと
- TPO によって使い分けていた自分を止めることで、心の負荷を低減させ、無駄なストレスを排除しよう
- 自分のすべてをしり、他人に隠し事を極力なくし、裏表がなく、恥を笑いに変えられる生きかたをしよう
- 人生の終着地において、自分の周りにいる人に「ありがとう」って言われて、後悔の無い生き方をしよう
    - 幸運の女神様には後ろ髪はない（から、逃したら掴めない）とも言いますしね。


# あとがき

ちょっと、言い過ぎたかな？とも思ったんですが、
ちゃんとわかってくれて、それからは表で会話してくれるようになったうえ、
その開発チームの方針と定めてくれたことがとても嬉しかった :heart: 

熱い思いはいつ迄も持っていたいですね。鉄は熱いうちに打てって言いますけど :laughing:
リザーブドインスタンス導入

# 背景
EC2の利用料金を下げたい。

# 目的 & ゴール
リザーブドインスタンスの導入

# 作業内容

## リザーブドインスタンスとは？（EC2）
1年や3年といった長期間の利用をリザーブ（予約）することで、大幅な割引を受けられるサービス。

### 支払い方法
以下の3種類から選べる：
- **前払いなし（NURI）**
- **一部前払い（PURI）**
- **全額前払い（AURI）**

### 割引率の決定要素
1. **インスタンスの種類**
2. **契約期間**（契約期間が長い方が割引率が高い）
3. **支払い方法**（全額前払い > 一部前払い > 前払いなし の順で割引率が変動）

## リザーブドインスタンスの種類

### スタンダード
- 割引率が高めに設定されている。
- 一度支払ったら原則変更不可能。
- 契約期間は1年または3年から選べる。

### コンバーティブル
- 割引率が低めに設定されている。
- 同等以上のリザーブドインスタンスであれば差額の支払いで交換可能。
- 契約期間は1年または3年から選べる。

## リザーブドインスタンスのメリット
- オンデマンドインスタンスに比べて大幅なコスト削減が可能。
- 支払い方法を選べる。
- 購入期間を選べる。

## リザーブドインスタンスのデメリット
- 途中で解約できない。
- 支払い済みの場合、後からキャンセルできない。
- 運用の柔軟性に欠ける。
- 事前にスペックを固定する必要があり、変更ができない。


# 価格調査

### 現在使用中のEC2（オンデマンドインスタンス）
- **インスタンスサイズ**: t4g.medium  
- **1時間**: USD 0.0432（約6.7円）  
- **24時間**: USD 1.0368（約160円）  
- **1ヶ月**: USD 31.104（約4790円）  
- **1年**: USD 373.248（約57480円）

### リザーブドインスタンスの料金比較

| 契約期間 (年) | 支払い方法           | 料金 (月換算) | 現在との比較 (月) |
|---------------|----------------------|---------------|-------------------|
| 1             | 前払いなし           | 3058円        | -1732円           |
| 1             | 一部前払い (初月17402円) | 2882円        | -1908円           |
| 1             | 全額前払い (初月34188円) | 2772円        | -2018円           |
| 3             | 前払いなし           | 2102円        | -2688円           |
| 3             | 一部前払い (初月35000円) | 1884円        | -2906円           |
| 3             | 全額前払い (初月65758円) | 1774円        | -3016円           |

# 本番稼働中のインスタンスへの適用方法
- 必要な作業なし。該当するインスタンスに自動で適用される。

# 注意点
- リザーブドインスタンスは購入後のキャンセルが一切できない。
- 違うアカウントで購入するミスに注意。
【Windows】初心者にも分かるようにVSCodeでC++とRaylibの環境構築をする

日本語で、あまりVSCodeでRaylibを使う方法が書かれていないので、初心者にもわかりやすいようにここに書きたいと思います。

参考
>https://www.youtube.com/watch?v=PaAcVk5jUd8

## 1. Raylibをダウンロード
まず。https://raylib.com にアクセスしてください。そしたら、赤い枠でおおわれているDownload Nowをクリックしてください。
そしたら、灰色の支援をしないでダウンロードをクリック。
赤い枠のダウンロードをクリックして、ダウンロードが開始されます。
終わったら、Win+Eを押し、エクスプローラーを開いてください。
ダウンロードファイルにraylib installerがあるので、それをダブルクリックしてください。インストーラーが起動します。何も変更する必要がないので、NextやInstallだけを押してください。これで、Raylibのインストールが完了します。
## 2.C/C++(MinGW)をインストール
ダウンロードが終了したらwindowsキーを押してpathと入力してください「システム環境変数」を開いてください。そしたら、環境変数(N)→上のxxのユーザー環境変数のPathをクリックしPathの行を青くしてください。そしたら、上のほうの編集をクリックしてください。新規をクリックしてください。そしたら
```
C:\raylib\w64devkit\bin
```
をコピペしてください
ついでに、あとで行うMakefileの使うためのPathを追加します。
また同じく、新規を押し、
```
C:\GnuWin32\bin
```
これをコピペしてください。最後に、3つのpath環境変数のウィンドウがあると思うので、すべてOKをクリックしてください。これで完了です。

## 3.Makefileをダウンロード
これは
>https://qiita.com/BARANCE_TW/items/c7ffdb311df84d47bddd

これを見てインストールしてください。

::: note warn
ただし「makeコマンドを実行できるようにパスを通す」以降はやらなくていいです。
:::

## 4.VSCodeをダウンロード、設定をする
まず、
>https://code.visualstudio.com/download

ここに移動してください。左の、青い四角形で囲われたWindowsをクリックして、ダウンロードしてください、
Win+Eを押しエクスプローラーを開いて、ダウンロードフォルダーにあるVSCodeのインストーラーを開いてください。

:::note warn
インストーラー内で特に何も設定を変更する必要はないです、でも、 
PATHへの追加(再起動後に使用可能)はチェックをできれば入れてください。
:::

VSCodeをダウンロードできたら、起動し、左の欄にある、正方形が4つ並んでいて、右上が欠けているようなアイコンをクリックしてください。そしたら、Maeketplac... のところに C++ extension packと入力してください。公式マークでMicrosoftと書いてあるやつのC++ extension packをインストールしてください。
次に、Makefile toolsと入力し、Microsoftが作ったMakefile toolsをダウンロードしてください。
最後に、Japanese languageと調べて、地球儀のアイコンの Japanese Language Pack for Visual Studio Code をダウンロードしてください。
これでVSCodeのダウンロード、設定は終了です。

そしたら、一度PCを再起動してください。

## 5.RaylibのVSCodeテンプレートをダウンロード

>https://github.com/educ8s/Raylib-CPP-Starter-Template-for-VSCODE-V2

ここに行ってください。そしたら、右上の<>Codeをクリックし、Download ZIPをクリックしてインストールをしてください。
    そしたらWin+Eをクリックし、ダウンロードフォルダーにzipファイルがあると思うので、これを1クリックし、上にあるすべて展開をクリックして、zipファイルを解凍してください。そしたら、そのファイルを開き、main.code-warkspaceをダブルクリックしてください。VSCodeが開くと思うので、そしたら、srcの中のmain.cppをクリックして、コードを開いてください。そしたら、F5キーを押してください、Windowが現れ、ウィンドウに跳ね返るボールが出てきたら、環境構築は完了です！

## 6.環境構築できたけど、どうやって勉強すればいいの？という方へ
自分的には、https://www.raylib.com/examples.html のコードを写経するのがおすすめです。また、YouTubeでC++ Raylib Tutorialと調べるとでてくるチュートリアルをやることも良いと思います。

## 7.終わりに
お疲れさまでした。最後に、エラーが発生してすすめない方や、質問がある場合は、遠慮なくコメントしてください！できる限り答えます。また、誤字があった場合も言ってくださると幸いです。よき*Programming Life*を！
page.goto メソッドとは

page.goto メソッドは、Playwrightのブラウザ自動化ライブラリで、指定したURLにページを遷移させるために使用されます。

## 1.URLにナビゲート
`page.goto(url)` を呼び出すと、指定したURL（url）にブラウザのページが遷移します。これにより、新しいページがロードされ、指定されたWebページが表示されます。

## 2.非同期処理
`page.goto` は非同期メソッドであり、`await` を使って完了を待つことができます。ページの遷移が完了するまで次の処理が進まないようにするため、通常 `await` を使用します。

## 3.オプション
```react
await page.goto('https://example.com', {
  waitUntil: 'networkidle', // ページのネットワーク接続がアイドル状態になるまで待つ
  timeout: 60000, // 最大60秒待機
});
```
`page.goto` にはオプションを指定することができます。例えば、ページの遷移時にタイムアウトを設定したり、リダイレクトを無視するなどの設定が可能です。

## まとめ
`page.goto` メソッドは、テストシナリオの中でページを特定のURLに遷移させる際に非常に便利です。