OmniAICreator/Qiita-1.07M huggingface dataset:
Aura コンポーネントを Lightning Web コンポーネントに移行する



https://medium.com/@rajasneha20/lightning-web-components-migration-cheatsheet-c8ef6352ee04

# バンドル

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/f723c470-0485-6026-a98e-4701109b17e3.png)

# 属性

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/a2673103-8af1-fa68-8751-e00950bb33bb.png)

# 繰り返し

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/b2133191-5818-3e0b-7d79-06375df7bf2d.png)


# if　条件

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/3f060504-147c-0032-a941-94872dc8f0ce.png)


# ライフサイクル

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/4eba5408-d95f-c829-97c4-c04ec6fb5cab.png)

# ?

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/9cc2b5a2-4537-7f1a-a2f2-f23ac291190f.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/e5030d4f-062b-3066-c1f2-1b388a83cfe9.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/0b1a2cde-7f65-fa60-11ab-1e759fa28703.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/86dd51ad-4f70-46bb-f429-f704498119de.png)


# イベント

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/2079506c-c10c-af9f-a0a8-5f3d4b2cfcc9.png)

# CSS

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/f54d4fc6-e5b4-1ad3-6ef8-7be3d92117d6.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/418dd80e-62a2-7002-cdbc-52f394307090.png)

# Apexのコール

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/ea442e5f-609f-ad72-68ad-4ac99abde23e.png)
Prologで動的に述語を定義する

## 概要

SWI-Prologのドキュメントで[Managing (dynamic) predicates](https://www.swi-prolog.org/pldoc/man?section=dynpreds)の項目を読んでいて、ある程度使い方がわかったのでまとめる

## 使い方

### 節や事実の定義

動的に述語(節や事実)を定義するには以下の述語を利用する。

- `asserta` : 前回定義した述語の前に定義する
- `assertz` : 前回定義した述語の後ろに定義にる

以下はファイルから読み込んだデータを元に事実を定義する例

`dynamic_fact.txt`は以下のようにしておく

```txt
first
second
third
```

```prolog
read_file_lines(FilePath, Lines) :-
    open(FilePath, read, Stream), % ファイルを読み込みモードで開く
    read_lines(Stream, Lines), % ファイルから行を読み込む
    close(Stream). % ファイルを閉じる

read_lines(Stream, []) :-
    at_end_of_stream(Stream), !. % ファイルの終端に達した場合は空リストを返す

read_lines(Stream, [Line|Rest]) :-
    \+ at_end_of_stream(Stream), % ファイルの終端に達していない場合
    read_line_to_codes(Stream, LineCodes), % 行を読み込む
    atom_codes(Line, LineCodes), % 文字コードをアトムに変換
    read_lines(Stream, Rest). % 次の行を読み込む

test_dynamic :-
  read_file_lines('./dynamic_fact.txt', Lines),
  forall(member(Line, Lines), (
    asserta(myfact1(Line)), % 事実 myfact1() を定義
    assertz(myfact2(Line))  % 事実 myfact2() を定義
  )),
  % 事実の先頭から検索するので結果が異なる
  myfact1(X1), writeln(X1), % third
  myfact2(X2), writeln(X2)  % first
  .

test_dynamic. % test_dynamicの実行  
```

### 節や事実の削除

節や事実を削除するには以下の述語を利用する

- `retract`

「節や事実の定義」の項目で定義したコードを以下ように書き換えると事実が削除されて結果が変わる

```prolog
test_dynamic :-
  read_file_lines('./dynamic_fact.txt', Lines),
  forall(member(Line, Lines), (
    asserta(myfact1(Line)),
  )),
  retract(myfact1(third)),  % myfact1(third) を削除
  myfact1(X1), writeln(X1)  % second (thirdを削除したため結果が変わる)
  .
```

### 節や事実をまとめて削除

節や事実をまとめて削除するには以下の述語を利用する

- `retractall`

allと書いてあるが、必ずしもすべての節や事実を削除するのではない点に注意。
特定の事実や節以降のデータを消す場合は1,2番目の例のようにする。
全ての事実や節を削除したい場合は3番目の例のようにする。
また `abolish`とは述語自体を削除するわけではないので、削除後に参照すると3番目の例の結果のように`false` (見つけられなかった)になる。

```prolog
test_retractall :-
　　　　% 1. 特定の事実を指定して削除 (assertz)
  assertz(myfact1(first)),
  assertz(myfact1(second)),
  assertz(myfact1(third)),
  retractall(myfact1(second)),
  myfact1(X), writeln(X),     % first (second, thirdを削除したため)
  % 2. 特定の事実を指定して削除 (asserta)
  asserta(myfact2(first)),
  asserta(myfact2(second)),
  asserta(myfact2(third)),
  retractall(myfact2(second)),
  myfact2(Y), writeln(Y),!,   % third (second, firstを削除したため)
  % 3. 全ての事実を削除
  asserta(myfact3(first)),
  asserta(myfact3(second)),
  asserta(myfact3(third)),
  retractall(myfact3(_)),
  myfact3(_).                 % false (述語を削除したわけではないのでエラーにはならない)
```

### 述語の削除

特定の述語を削除するには以下の述語を利用する

- `abolish`

以下は事実として定義した述語を削除するコード
削除しているので、読み取りを行おうとするとエラーになる

```prolog
test_abolish :-
  assertz(myfact1(first)),
  assertz(myfact1(second)),
  myfact1(X), writeln(X),
  abolish(myfact1/1), % 述語なので引数の数も指定する
  myfact1(_).         % Error
```

## まとめ

予めわかっているような定数は`asserta`, `assertz`を利用せずに、直に定義してしまえば良いので、用途としては、動的に生成したデータやファイルに書かれているデータを事実や節として定義したい場合に利用するのではないかと思います。

また、今回は解説していませんが、フラグやトライ木を実現する述語も存在するようです。
AWSでAurora MySQLデータベースを使用するときの監視設定についてまとめてみた


## メモリを監視する

Aurora MySQLはパフォーマンス最適化のため、メモリの80%から90%が利用されるように設定されている。(MySQLのデフォルト設定)

メモリの80%から90％までが利用されるようになっている理由はデータベースのパフォーマンスをあげるためです。空きメモリがあると積極的にバッファプールに利用されます。
バッファプールは以下のパラメータで設定されます。

**innodb_buffer_pool_size**：InnoDBバッファプールのサイズ。基本的に物理メモリの 75% に設定されています。


このように積極的に空きメモリはバッファに利用される為、メモリ使用率が90%以下の場合は気にしなくて大丈夫みたいです。
メモリ負荷レベルを 95% 未満に保つことがベストプラクティスのためメモリの使用率が90~95を超えたらアラートが発報するように設定しておくのがよさそうです。

AuroraやRDSにはメモリ使用率のメトリクスがないのでFreeableMemoryをしきい値90~95%で設定するとよいでしょう。

また、メモリが枯渇していないかを確認するにはFreeableMemoryだけでなく、SwapUsageやBufferCacheHitRatioといった指標が役に立ちます。

**SwapUsage**　大量のスワップが使用されている場合はメモリが枯渇している可能性が高い
メモリの状態を確認するのにメトリクスが役立つ
**BufferCacheHitRatio**　バッファキャッシュによって処理されるリクエストの割合を測定、ヒット率が高ければ効率よくバッファキャッシュを使用してDBが動作していることがわかる。


**InnoDB(イノデービー)とは**
MySQLについて調べていると出てくるInnoDB(イノデービー)ですが、何かというMySQLで使用できるストレージエンジンの一つです。

## ストレージを監視する

Auroraのストレージは自動拡張するので監視不要と思っていたのですが、Auroraのストレージには２種類あるみたいです。
クラスターボリュームとローカルストレージです。

**クラスターボリューム**
複数のAZにまたがって配置されるストレージです。最大128テラバイトまで自動的に拡張されます。

**ローカルストレージ**
エラーログ、一般ログ、スロークエリログ、監査ログ、および InnoDB 以外の一時テーブルの保存に使用される。自動拡張しないためDBインスタンスのクラス変更するしかない。ローカルストレージが枯渇するとエラーになり障害が発生してしまうので注意が必要。


参考記事


https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/Aurora.BestPractices.html

https://repost.aws/ja/knowledge-center/aurora-mysql-local-storage

https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/CHAP_Troubleshooting.html#Troubleshooting.FreeableMemory
GitHub Actions CI/CDを使ってPyPIに自動アップロード

## はじめに

GitHub Actions CI/CDを利用すると、GitHubでのイベント発生をトリガーに、一連のコマンドを自動実行できます。これを活用して、Pythonパッケージをビルドし、PyPIに自動公開するワークフローを構築できます。


こちらの記事もおすすめ

https://hamaruki.com/resolving-errors-in-hugging-face-ci-cd/

https://hamaruki.com/codelumia-automatically-generate-decryption-documentation-for-github-repositories/

## 事前準備

- PyPIのアカウントを作成しておく
- プロジェクトのGitHubリポジトリを用意する

## PyPIへの信頼できる公開の設定

PyPIへの信頼できる公開（Trusted Publishing）を設定するには:

1. PyPIのアカウント設定ページで、新しいプロジェクトを登録
2. 信頼できる公開者（トラステッドパブリッシャー）を設定
   - GitHubリポジトリのオーナー名、リポジトリ名、ワークフロー名を指定
   - GitHub環境名（例: `pypi`）を指定

## ワークフロー定義ファイルの作成

GitHub Actionsのワークフローは、リポジトリの `.github/workflows` ディレクトリ内のYAMLファイルで定義します。

1. リポジトリのルートディレクトリに`.github/workflows`ディレクトリを作成します。

2. `.github/workflows`ディレクトリ内に`publish-to-pypi.yml`ファイルを作成し、以下の内容を記述:

```yaml
name: Publish Python Package

on:
  push:
    branches:
      - main
    tags:
      - '*'

jobs:
  publish:
    runs-on: ubuntu-latest
    environment: 
      name: pypi
      url: https://pypi.org/p/sourcesage
    permissions:
      id-token: write
    steps:
      - uses: actions/checkout@v3
      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: '3.x'
      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install build
      - name: Build package
        run: python -m build
      - name: Publish package
        uses: pypa/gh-action-pypi-publish@release/v1
        with:
          skip-existing: true
```

この設定では、以下の条件が満たされたときにワークフローが起動します：

- プッシュイベントがmainブランチで発生する
- プッシュされたコミットにタグが付けられている

### ワークフローの説明

1. `on`: ワークフローのトリガーを定義します。
   - `push`イベントをトリガーとし、`main`ブランチとすべてのタグを対象とします。
2. `jobs`: ワークフローのジョブを定義します。
   - `publish`ジョブを定義し、Ubuntu環境で実行します。
   - `environment`セクションで、使用するPyPI環境（`pypi`）とパッケージが公開されるPyPIプロジェクトのURLを指定します。
   - `permissions`セクションで、信頼された公開（Trusted Publishing）に必要な`id-token`の書き込み権限を付与します。
   - `steps`セクションで、以下のステップを定義します：
     1. リポジトリをチェックアウトします。
     2. Pythonの環境をセットアップします。
     3. 依存関係をインストールします。
     4. `build`を使用してパッケージをビルドします。
     5. `pypa/gh-action-pypi-publish`アクションを使用してパッケージをPyPIに公開します。

## 自動化の実行

上記のワークフロー定義を含むコミットをプッシュし、mainブランチにタグを付与すると、GitHub Actions上でワークフローが実行されます。

ワークフローが正常に完了すると、PyPIにパッケージが公開されます。

## まとめ

本記事では、GitHub Actions CI/CDを使ってPythonパッケージをPyPIに自動公開する方法を解説しました。

- PyPIの信頼できる公開設定
- ワークフロー定義ファイルの作成
  - 対象のブランチ・タグの指定方法
- ジョブの定義とアクション活用

適切なワークフローを構築し、mainブランチでタグ付けされたコミットに対して自動的にパッケージの公開を行うことで、開発の効率化が図れます。

## 補足: パッケージのビルドとテスト

パッケージのビルドとテストは、以下のコマンドで行うことができます。

### ビルド

```bash
python setup.py sdist bdist_wheel
```

### テスト（TestPyPIへの公開）

```bash
twine upload --repository pypitest dist/*
```

### 本番（PyPIへの公開）

```bash
twine upload --repository pypi dist/*
```

ただし、本記事で解説したGitHub Actionsを用いた自動化により、これらの手動でのビルドや公開は不要になります。タグ付きのコミットをmainブランチにプッシュするだけで、自動的にビルド・テスト・公開が行われます。
new Date()を使いこなすには、形式の統一が鍵！

# 概要
JavaScriptにおけるnew Date()は、単なる日付取得ツールではありません。日付操作はもちろん、タイムゾーン変換、フォーマット変換、相対日付計算など、多彩な機能を備え、開発を支える強力なツールです。しかし、実装方法によって異なる挙動になる可能性があるため、意図しない結果を招きやすい落とし穴も存在します。

この記事では、```new Date()```を使った日付の値を定義する上で注意すべきポイントについて紹介しています。

# new Date()を使った初期化に気を付けましょう
new Date()はいろんな方法で定義することができます。
たとえば、下記の4つの方法で```new Date()```を使って日付を定義することができます。
```javascript
// 現在時刻取得
const now = new Date()

// 文字列から生成
const dateFromStr = new Date("2023-12-25")

// 数値から生成
const dateFromNumber = new Date(2023, 11, 25)

// タイムスタンプから生成
const dateFromMiliSec = new Date(1672102400000)

```

"いろんな使い方で定義できて、とても便利ですね〜"
　と
思うかもしれませんが、下記の結果に気づいたときはとてもショックでした。


## 数値からnew Date()で初期化するとき
その他の方法と違って、数値で日付を定義する場合、第２パラメータの月の値は0から始まる値となるため、下記の例では```11+1```が実際に定義した日付になります。
はい、11を書いて、12月になるので注意してください。
```javascript
const dateFromNumber = new Date(2023, 11, 25)
// 出力：Mon Dec 25 2023 00:00:00 GMT+0900 (Japan Standard Time)
```

#### 対策：
数値だけで日付を指定する場合、new Date()の２番目のパラメータは対象月から１を引いた値を指定しましょう。

## 文字列からnew Date()で初期化するとき
ちなみに、下記のコードは日本の東京のタイムゾーンで実行しています。
```javascript
// 区切り記号にスラッシュを使う形式の文字列 下記は同値
// "2024,05,01", "2024.05.01", "2024 05 01", 
// "2024,5,01", "2024,05,1"
// "2024.5.01", "2024.05.1"
// "2024-5-01", "2024-05-1", "2024-5-1"
console.log(new Date("2024/05/01"))
// 出力：Wed May 01 2024 00:00:00 GMT+0900 (Japan Standard Time)

// 区切り記号にハイフンを使う形式のISO文字列
console.log(new Date("2024-05-01"))
// 出力：Wed May 01 2024 09:00:00 GMT+0900 (Japan Standard Time)
```


なぜか、```yyyy-MM-dd```だけの時刻が9時間ずれています。
たとえば、上記の時刻をGMT+8(中国標準時間)に換算すると、
区切り記号にスラッシュを使う形式の文字列は日付が変わるのに対して、
区切り記号にハイフンを使う形式のISO文字列は日付が変わりませんでした。

```javascript
// 区切り記号にスラッシュを使う形式の文字列
Wed May 01 2024 00:00:00 GMT+0900 (Japan Standard Time)
=> Tue Apr 30 2024 23:00:00 GMT+0800 (China Standard Time)

// 区切り記号にハイフンを使う形式のISO文字列
Wed May 01 2024 09:00:00 GMT+0900 (Japan Standard Time)
=> Wed May 01 2024 08:00:00 GMT+0800 (China Standard Time)
```

すでに気付いているかもしれませんが、下記の２パターンの動作結果になります。

1. [区切り記号にハイフンを使う形式のISO文字列](https://ja.wikipedia.org/wiki/ISO_8601)の場合：
 => UTC時間（GMT+0000）で日付が定義され、ローカル日付に自動的に換算されます。
2. それ以外の形式の場合：
 => ローカル時間でそのまま日付が定義されます。

もしバラバラな方法で日付を定義すると、海外出張をしているユーザーの画面に表示される値は実際のデータと異なる日付になる場合がありますので、注意が必要です。

#### 対策：
バックエンド側から戻り値をnew Date()に渡したい場合は、同じフォーマットになるようインタフェースの仕様から決める必要があります。
もしそれが難しい場合は、[date-fns](https://date-fns.org/)などのライブラリを使って、formatしたstring値をnew Date()に渡しましょう。

```javascript
import { format } from 'date-fns';

const date = new Date(format(returnValue, 'yyyy-MM-dd'))
```

上記コード例はあくまで参考であり、具体的な実装は状況に応じて調整する必要があります。
より高度な日付処理が必要な場合は、[Moment.js](https://momentjs.com/), [Day.js](https://day.js.org/)などのライブラリも検討しましょう。
# 結論
- new Date()に数値だけを渡して日付を設定する際は、2番目のパラメータ（月）が対象月から1を引いた値になることに注意しましょう
- バックエンドとのやり取りで使用する日付フォーマットを明確に定義しましょう
- new Date()に渡す値はフォーマットを統一しましょう
Windows Server 2022 Datacenter Azure Edition VM のライセンスが非アクティブ化される

# 現象
Windows Server 2022 Datacenter Azure Edition VM で
2024年4月中旬以降、サーバーログイン時に下記のメッセージが表示されます。

![エラー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778723/bd13123d-fcd9-aa84-93c3-5e2cd6976d65.png)

:::note warn
Windows Server 2022 Datacenter Azure Edition VM は、Azure またはサポートされているAzure Stack ハイパーバイザーで実行されていないか、サポートされているAzure StackでAzureの特典を有効にしていないため、非アクティブ化されました。Azure特典を有効にするには、[Windows Admin Center] > [Azure特典を有効にする]でクラスター設定に移動します。
:::

# 回避策
Microsoft Learn に同様の報告があり、下記の回答を見つけました。

参考: [Windows Server 2022 Datacenter Azure Edition VM deactivated in MS Azure due to lack of "Azure Stack Hypervisor"](https://learn.microsoft.com/en-us/answers/questions/1659610/windows-server-2022-datacenter-azure-edition-vm-de)
> I've had the following back form Microsoft regarding this. "Our team has discovered that the root of the problem is a glitch in the license activation sequence. Thankfully, this error message is harmless and won't affect your system's performance. Rest assured, we're actively working on a solution, which will be included in the upcoming monthly update."
> これに関してマイクロソフトから次のような返答がありました。 「私たちのチームは、問題の根本がライセンス アクティベーション シーケンスの不具合であることを発見しました。幸いなことに、このエラー メッセージは無害であり、システムのパフォーマンスには影響しません。ご安心ください。現在、解決策に積極的に取り組んでいます。今後の月例アップデートに含まれる予定です。」

エラーメッセージは無害、今後のアップデートで対応とのこと。
また、以前にも似た事象を経験したことがあったので、念のためサーバー内のライセンス状況を確認してみました。

# ライセンス状況の確認
#### Windows設定のライセンス
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778723/b8a15c24-0c49-9000-f09f-59768dc76245.png)
<font color="red">**ライセンス認証されていません**</font>
<br>
#### Windows内部のライセンス
``` cmd:コマンドプロンプト
cscript c:\windows\system32\slmgr.vbs /dlv
```
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3778723/0d712397-4e23-b70f-c01a-9a5e66fdd0c7.png)

<font color="blue">**ライセンスされています**</font>
<br>
現象的に2022年に発生した「**<font color="red">表示上ライセンス認証されていないように見えるが、実際はライセンス認証できている</font>**」状況によく似ています。
参考: [Windows Server 2022 Azure Editionのバグ](https://qiita.com/hidekko/items/61fb19cfb9c7f8999a88)

# 対応
上記の状況から大きな影響はないと判断し、しばらく様子を見ることにしました。
今後のアップデートで状況が変わったら追記します。
【UI】分かりやすさのために事実を変える？


## 前提

ユーザーは非技術者だと想定する。

## 本文

例えば、画像を線画に変換するアプリを作るとして、
輪郭の抽出のためのパラメーター(※)を画面でいじれるようにしたい。とする。

※ 簡単のため、このパラメーターを輪郭値と呼ぶことにする。

輪郭値は以下の特徴がある。
* 小さいほど色の境界部分が輪郭だと判定されやすい。
* 大きいほど色の境界部分が輪郭だと判定されにくい。
* 最小値0、最大値200

この輪郭値を愚直にUIに落とし込もうとすると以下のようになると思われる。

<img width=600 src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649673/5ca4e143-2eed-2eb5-7a94-67f11bb84a01.png>

このように実装するとUIの値と、システムとしての値が全く同じになるため管理が簡単というメリットがある。

しかし、数値が小さいほど輪郭判定が強くなり、大きいほど判定が弱くなる。という挙動は人間の直感に反しており、無駄に脳みそを使ってしまう。

そのため、愚直にシステムの値を使わずに人間の直感にあった数値を使ったほうがUI/UXの向上につながると思われる。

以下はその実装例
`輪郭値 = 200 - UI上の値`
という変換が必要になるが、ユーザーの脳には優しくなる。

<img width=600 src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649673/fb029ec3-248f-0927-08b3-81cc42fad9c5.png>
Power Automate：承認のリマインド機能を実装する

# 実装するイメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368087/5364e469-122b-ab25-5f0f-4775cce45293.png)

※待ち時間　アクションの検索方法：遅延
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368087/9b05ed27-af7d-e195-f128-64bbce3d3e51.png)

# 参考サイト
https://artisan.jp.net/blog/power-automate-approval-remainder/
"Telkom University: Menggali Potensi dengan Fasilitas Berkualitas"

![Telkom University.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3782275/a47ec2dc-584b-61fc-3a66-f799bc9f6bc3.jpeg)
<a href="https://telkomuniversity.ac.id/">Telkom University</a>, sebagai salah satu universitas terkemuka di Indonesia, tidak hanya menawarkan pendidikan berkualitas tetapi juga dilengkapi dengan beragam fasilitas untuk mendukung pengalaman belajar dan kehidupan kampus mahasiswa. Berikut adalah beberapa fasilitas utama yang tersedia di <a href="https://telkomuniversity.ac.id/">Telkom University</a>:

1. **Perpustakaan Digital**: <a href="https://telkomuniversity.ac.id/">Telkom University</a> memiliki perpustakaan digital yang lengkap dengan koleksi buku, jurnal, dan sumber daya elektronik lainnya. Mahasiswa dapat mengaksesnya secara online dari mana saja, memfasilitasi penelitian dan studi mandiri.

2. **Laboratorium Teknologi**: Kampus ini dilengkapi dengan berbagai laboratorium teknologi yang dilengkapi dengan perangkat keras dan perangkat lunak terkini. Ini termasuk laboratorium komputer, laboratorium jaringan, dan laboratorium teknologi informasi lainnya yang digunakan untuk penelitian dan praktikum.

3. **Ruang Kelas Interaktif**: <a href="https://telkomuniversity.ac.id/">Telkom University</a> memiliki ruang kelas yang dilengkapi dengan teknologi canggih, seperti proyektor interaktif, layar sentuh, dan sistem audiovisual mutakhir. Ini menciptakan pengalaman belajar yang interaktif dan mendalam bagi mahasiswa.

4. **Pusat Olahraga dan Rekreasi**: Kampus ini juga dilengkapi dengan fasilitas olahraga dan rekreasi, termasuk lapangan olahraga, pusat kebugaran, dan ruang serbaguna. Mahasiswa dapat menggunakan fasilitas ini untuk menjaga kesehatan fisik dan menjalin hubungan sosial.

5. **Pusat Kesehatan Mahasiswa**: Telkom University memiliki pusat kesehatan mahasiswa yang menyediakan layanan kesehatan dasar, konseling, dan dukungan medis lainnya. Ini membantu mahasiswa dalam menjaga kesehatan dan kesejahteraan mereka selama studi di kampus.

6. **Fasilitas Kampus Lainnya**: Selain itu, Telkom University juga dilengkapi dengan berbagai fasilitas lain, termasuk kantin, pusat layanan mahasiswa, ruang pertemuan, dan area parkir yang luas. Semua ini dirancang untuk memenuhi kebutuhan sehari-hari mahasiswa dan memastikan pengalaman kampus yang menyenangkan dan produktif.

Dengan berbagai fasilitas yang lengkap dan modern ini, Telkom University memberikan lingkungan yang kondusif untuk pembelajaran, penelitian, dan pengembangan pribadi mahasiswa. Ini tidak hanya mendukung pencapaian akademik mereka tetapi juga membantu mereka untuk tumbuh dan berkembang sebagai individu yang berdaya dan berprestasi.
windows terminalで検索

## 概要
windows terminalは面白い使い方ができる。

## 検索
cntl+shift+fでterminalの全部から検索できる。
今までそういうことができるというのを知らなかったので、最近qiitaにあげていなかったので報告

## マークモード
そうなると、カーソルを動かしたくなる。つまり、コピペである。
普通にマウスではできるが、カーソルでできないのかと見てみるとあった！
cntl+shift+mでマークモードになって、これでカーソルを移動できる。
おお、知らなかった。

## 矩形選択
通常はキーに割り当たっていない。
設定画面で操作の最初に「新規追加」というのがあるので
「ブロック選択の切り替え」というのにキーを割り当てれば、矩形選択もできる

## cntl+shift+p
コマンドパレットがでて、実行できるコマンドが一覧化される
いろんなことができるんだねえ・・驚き

## 全履歴の格納
cntl+shift+aで全部クリップボードにはいる。
gcb > xx.txt
で全部の履歴を保存できる。
LangChainについて学んだのでみんなにまとめて共有します！

# 0. この記事の導入

ゴールデンウィーク中は新たな技術を中心に身に着けていく所存です。
もう新しい技術を学ぶ毎日が楽しすぎて楽しすぎて。。

会社からはUdemyの受講し放題。そして書籍の購入し放題という環境をいただいたので今回は、下記のUdemyの講座を受講してみました。

https://www.udemy.com/course/langchain-llm/?couponCode=ST2MT43024

この講座では下記のようなことが身に付きます。

- LangChainを使ったLLMアプリ構築を基礎から体験と共に学びます。
- LangChainが持つ様々な機能の使い方を学びます。
- LangChainの様々な応用を学びます。
- LangChainの全体像、そしてその可能性について学びます。

またコースの内容は下記のようなセクションに分かれております。
1. LangChainの概要
1. LangChainの基礎
1. LangChainの様々な機能
1. LangChainの応用
1. ボーナスレクチャー

このブログではコースごとに実践したことや身についたことを書き連ねていきます。

# 1. LangChainの概要
Windows Sandboxを基本からまとめてみた【基礎】

## Windows Sandboxとは？

- proエディションでのみ使える機能であり、Windowsの中にもう一つのWindowsの環境を仮想的に作成する機能

- 実機となる環境をホスト、仮想環境をゲストと呼ぶ
- ホストとゲストの関係は独立していてお互いに行き来できない
- 仮想環境を簡単に構築・破棄できる
- 構築した仮想環境を保存できない

## 使い方

①ファイル名を指定して実行(Windowsキー + R)

②optionalfeatures.exeを起動する

③Windows Sandboxにチェックを入れて有効化し、再起動する

④スタートメニュー ⇨ 全てのアプリにWindows Sandboxが並んでいるので起動する ⇨ 仮想環境のWindowsが開く

## Windows Sandbox構成ファイル(wsbファイル)

- XML形式の設定ファイル
- 起動する仮想環境をカスタマイズできる

```Download.wsb
<?xml version="1.0" encoding="utf-8"?>
<Configuration>
  <Version>1.0</Version>

  <Startup>
    <Network>
      <Enable>True</Enable>      <InternetAccess>True</InternetAccess>  </Network>

    <SharedFolders>
      <Folder path="C:\Users\Public">
        <ReadOnly>False</ReadOnly> </Folder>
    </SharedFolders>

    <LogonCommands>
      <Command>notepad.exe</Command>  </LogonCommands>
  </Startup>

  <Resources>
    <GPU>
      <Mode>Dedicated</Mode>  </GPU>
  </Resources>
</Configuration>
```



## 参考サイト
[Windows may be best for development! Use Windows Sandbox!](https://www.youtube.com/watch?v=9kJc8ek_Kic)
あなたのコーディングを加速するXcodeのブックマーク機能


# XcodeのBookmark機能について

XcodeのBookmark機能は、コードの特定の部分に素早くアクセスするための便利なツールです。この機能を活用することで、プロジェクト内の任意の場所にブックマークを設定し、後から簡単にその場所に戻ることが可能になります。

## Bookmarkの設定方法

1. **Xcode**を開き、ブックマークを設定したいコードの行にカーソルを置きます
2. `Command + control + ^`を使用します。もしくは、`右クリック` > `Bookmark ”XXXX.swift” Line XX`を選択します

これにより、選択した行にブックマークが設定されます。

ファイル全体にブックマークを設定したい場合は、以下の手順を実行します：

1. **Xcode**を開き、ブックマークを設定したいファイルを選択します
2. `Command + Shift + control + ^`を使用します。もしくは、`右クリック` > `Bookmark ”XXXX.swift”`を選択します

これにより、選択したファイルにブックマークが設定されます。

## Bookmarkの一覧表示と移動

1. ブックマークを一覧表示するには、`Command + 3`を使用します。もしくは、ナビゲーターエリアの左から3番目のブックマークアイコンを選択します
2. 一覧から特定のブックマークを選択すると、そのブックマークが設定されたコードの行に直接移動します

## Bookmarkの削除

1. ブックマーク一覧を表示します
2. 削除したいブックマークを選択し、キーボードの`delete`を使用するか、`右クリック` > `Delete Bookmark`を選択します

以上がXcodeのBookmark機能の基本的な使い方です。
大規模なプロジェクトを管理する際には、この機能を活用することで、効率的に開発することができます。ぜひお試しください。
Windows11でMaixPy3 IDEの導入（ウイルス検知で挫折）

[インストール](https://wiki.sipeed.com/soft/maixpy3/zh/install/install.html)のページには、Windowsでは対応してないと書いてあるけどできるかやってみる
Windows11では動いた例が少ないと書いてあるのでとりあえずやってみる

# 環境構築

インストール中の様子
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3324101/6669318b-4891-29c8-9fd3-873ecdcdb626.png)
インストール中にポップアップウィンドウでデバイスドライバーのインストールが求められるので導入します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3324101/d8c44ed8-0b4c-309a-cbca-dabe00f492d9.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3324101/d3225ffe-e88f-31be-54ff-04e23c819a18.png)

こわい。一旦やめておくが、いらないPCが出たらチャレンジ予定
turborepo モノレポ環境で他からzodスキーマをimportしているとき、zodのバージョンを上げたらエラーが発生した

monorepoのrootで
```sh
pnpm -r update zod@lates
```
これで全部のパッケージのzodのバージョンが最新に上がるので直る。ただしちゃんと全部動くかどうかはCIで調べてください。zodはそんなに破壊的なことはないと思いますが、マイナーバージョンでもパッチバージョンでも異なると、たまにエラーを吐いて動かなくなります。そのときは全パッケージでバージョンをあわせてあげるとよろしいでしょう。少なくとも今回はよろしかったです。
[Ubuntu22.04+Redis7+php8]phpredisをインストール

## 環境

- さくらVPS
- Ubuntu(22.04)
- nginx(1.26.0)
- Redis(7.2.4)
- php(8.3.6)

## 手順

phpredis は git リポジトリ経由でインストールする

phpredis のインストールには phpize が必要で、phpize のインストールは php-dev という拡張パッケージをインストールすればよい

```リモート
sudo apt -y install php8.3-dev
```

phpredis をインストール

```リモート
git clone https://github.com/phpredis/phpredis.git
cd phpredis
phpize
./configure --enable-redis-igbinary
sudo make && sudo make install
```

php の redis 拡張モジュールを追加

```リモート
sudo apt -y install php8.3-redis
```
関数単体テスト2（フロントエンドのテスト③）

※この記事はドラフト版です。

# テストの実施
前回テストを行う準備ができたので今回は関数単体テストを行っていきます。
いつも準備がつらいです。AIがいい感じに環境準備してくれないでしょうか。

# 関数単体のテスト
## 前回までのおさらい
### 加算の関数
```typescript:add.ts
export function add(x: number, y: number) {
  return x + y;
}
```
### 加算の関数のテスト
```typescript:add.test.ts
import { add } from "./add";

test("1 + 1 は 2", () => {
  expect(add(1, 1)).toBe(2);
});
```
こんな感じのフォルダ構成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3743252/068cf596-551d-cd22-a752-2bc7e8ff00e4.png)

### 実行と実行結果
```bash
 npm run test
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3743252/967df975-5cba-99d8-3a7b-d14e5e3188dd.png)

# 前回のテストコードの解説
Jestのテストは次の形式で書くようになっています。
```typescript
test("テストタイトル", テスト用の関数)
```
テスト用の関数は次のように書きます。
```typescript
  () => { expect(テストしたい値).toBe(期待する値); }
//() => { expect(add(1, 1)).toBe(2); } ※今回はテストしたい値がadd関数の実行結果
```
期待する値をわざと関数が返さない値にしてみると
```typescript:add.test.ts
import { add } from "./add";

test("1 + 1 は 2", () => {
  expect(add(1, 1)).toBe(3);
});

```
#### 実行結果
テスト失敗となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3743252/7260936a-8e70-8947-b1a0-42e9c018702a.png)

# テストをグループ化する
## 例えば次の関数とテストを追加した場合
### 減算の関数
```typescript:sub.ts
export function sub(x: number, y: number) {
  return x - y;
}
```

### 減算のテスト
```typescript:sub.test.ts
import { sub } from "./sub";

test("1 - 1 は 0", () => {
  expect(sub(1, 1)).toBe(0);
});
```
### 実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3743252/443a8118-2fc3-1370-4c56-d2d9999c1907.png)

### 減算単体の実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3743252/d2b66e36-3529-fa9e-4464-bc74da650c9f.png)



## テストをまとめることができる
### テストコード
```typescript:arithmetic.test.ts
import { add } from "./add";
import { sub } from "./sub";

describe("算数", () => {
  test("1 + 1 は 2", () => {
    expect(add(1, 1)).toBe(2);
  });
  test("1 - 1 は 0", () => {
    expect(sub(1, 1)).toBe(0);
  });
});
```

### 実行結果
見え方が異なる
１つのテストでチェックマークが２つ付くようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3743252/4710c56d-a741-11bb-d0f8-611978f7097b.png)



# 条件分岐と例外処理
# 非同期処理のテスト
# まとめ
SAP Universal IDとは？間違ってSユーザを紐づけた際の解除方法

# SAP Universal ID は SAP サイト全体の統一アカウント

SAP Universal IDについては SAPの公式サイトの解説動画が一番わかりやすいです。
https://www.sap.com/japan/account/universal-id.html


>SAP Universal ID がお客様個人の SAP ID となるのに対し、S ユーザー ID は会社の管理者によって付与される会社の SAP ID であり、SAP Universal ID に基づく権限として使用することができます。

SAP公式サイトからの引用です。

## SAP Universal IDのメリット
SAP Universal  IDはどこか会社が付与指定くれるわけではなく、自分で作成するものです。

SAP Universal IDは個人のメールアドレスに紐づくので、Sユーザの切り替えがスムーズに行くため管理がしやすいです。

文字通りUniversal(普遍的)に使えるため、退職するとSユーザは削除されますが、このIDは残ったままです。


## SAP Universal IDとSユーザの関係を表すと
>SAP Universal ID(Gmailなどで作成したアカウントID)
　 →Sユーザ(会社A)
  　 →Sユーザ(会社B)

上記のような形でUniversal IDにSユーザが各会社のSユーザが紐づきます。


# SAP Universal IDとSユーザを間違って紐づけた際の解除方法は少しやっかい

noteはこちら。
2914815 - How to unlink users from an SAP Universal ID or delete the UID

インシデントでSAPに問い合わせる必要があります。

>There are 2 options available to request the unlinking of users from an SAP Universal ID and/or the deletion of an SAP Universal ID:

>Option 1 - Create a Case
Create a case for component XX-SER-UID and provide the following:
UID e-mail address
User(s) to unlink (S-user ID, P-user ID)
Reason why you want to unlink the user(s); or reason you wish to delete the UID

>Option 2 - Contact Customer Interaction Center (CIC)
If you are unable to create a case, send your request via e-mail to the Customer Interaction Center and provide the following:
UID e-mail address
User(s) to unlink (S-user ID, P-user ID)
Reason why you want to unlink the user(s); or reason you wish to delete the UID
[JavaScript] DOM/ Node/ Element の違い

# まとめ
- **DOM（Document Object Model=ドキュメントを物として扱うモデル）**：プログラム（JavaScript）からHTMLやXMLを自由に操作するための仕組み、データ構造
DOMツリーという階層構造を定義しているものがDOMという仕組み
- **Node**：DOMツリー（オブジェクトツリー）を構成する一つ一つの要素
- **Element**：Nodeの種類の一種（Element型Node）

# 詳細
## DOM
1. **プログラム（JavaScript）からHTMLやXMLを自由に操作するための仕組み、データ構造**
JavaScriptからHTMLドキュメントに要素を追加したり、ボタンクリック時のイベントを登録したり、スタイルや属性を変更したり、要素のサイズや位置を取得したり、こういったものはすべてDOMのAPIを使うことで操作できる。
1. **DOMツリー（オブジェクトツリー）という階層構造を定義しているものがDOMという仕組み**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955010/0d95c62f-6494-565b-0dce-d7290da44e62.png)

## Node
1. DOMツリー（オブジェクトツリー）を構成する一つ一つの要素（**ツリーのひとつひとつの箱（オブジェクト）**）
**Ex.**：html、bodyタグ、pタグ等
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955010/24bce2c3-c0e8-1610-d42c-997c9aa75311.png)

1. Nodeにはいくつか種類がある
   - Document（Document型Node・ドキュメントノード）
   - Element（Element型Node・エレメントノード）
   - Attr（Attribute型Node・属性ノード）　等 

## Element
1. Nodeの種類の一種（Element型Node）
1. 例えば、querySelectorAllといったメゾッドは提供されていないので、NodeをElementにしてquerySelectorAllを呼ぶといった処理を実装する。


# 補足
~~~html:DOM、Node、Elementの関係
DOM
 |- Node
    |- Document
    |- Element
    |   |- HTMLElement
    |   |- HTMLDivElement
    |   |- HTMLInputElement
    |   |- ...
    |- Attr
    |- ...
~~~

# 参考リンク
- [DOM, Node, Elementの違い](https://zenn.dev/sqer/articles/2d4def0f07bf04c5cc47)
- [DOM、Node、Elementの違いとそれぞれの使い分け](https://kuroeveryday.blogspot.com/2018/11/difference-between-dom-and-node-and-element.html)
- [JavaScript初心者でもすぐわかる！DOMとは何か？](https://eng-entrance.com/what-is-dom)
Java　コンストラクタ

### フィールドの初期値
|型名|フィールドの初期値|
|:---:|:----:|
|int型, short型, log型などの数値の型|0|　
|char型(文字)|￥u00000|
|boolean型|false|
|int[]などの配列型|null|
|String型などのクラス型|null|

￥は半角です(全角にしかならなかったです:cry:)

## コンストラクタ
クラスからオブジェクトを作成した際に、自動的に実行されるメソッド
```Hero.java
public class Hero{
 String name;
 int hp;
 public void attack(){
 }
 public Hero() {
  this.hp = 100; // hpフィールドを100で初期化
 } 
}
```
```Main.java
public class Main {
 public static void main(String[] args) {
  Hero h = new Hero(); // インスタンス生成と同時にコンストラクタによってHPに100が代入される
  System.out.println(h.hp);
 } 
}
```
attack()などの通常メソッドは呼ばれないと動かないが、Hero()メソッドはこのクラスがnewされた直後に自動的に実行される。
勇者インスタンスを生成しようとすると、うれたばかりの勇者は必ずHPが100になる
```結果.
100
```
::: note
##### コンストラクタと見なされる条件
①メソッド名がクラス名と完全に等しい
②メソッド宣言に戻り値の型が記述されていない(void)もだめ
:::

#### コンストラクタの定義
```
public class クラス名 {
 public クラス名() {
  自動的に実行する処理
 }
}
```

## コンストラクタを引数で受け取る
コンストラクタが毎回異なる追加情報を引数で受け取れるように宣言する

```Hero.java
public class Hero{
 String name;
 int hp;
 // 引数として文字列を１つ受け取る
 public Hero(String name) { 
  this.hp = 100; 
  this.name = name; // 引数の値でnameフィールドを初期化
 } 
}
```

#### 引数を伴うインスタンス生成
```
 new クラス名(実引数1, 実引数2, ....)
 ```
 ```Main.java
 public class Main {
 public static void main(String[] args) {
  Hero h = new Hero("ミナト");
  System.out.println(h.hp);
  System.out.println(h.name);
 } 
}
```
```結果.
100
ミナト
```

## 複数のコンストラクタが定義されていた場合
newするときに渡した引数の型、数、順番に一致するコンストラクタ１つだけが動作する

```Person.java
public class Person{
 String name;
 int age;
 public Person(String name){ 
 this.name = name;
 }
 public Person(String name, int age){
 this.name = name;
 this.age = age;
 }
 public Person() {
  this.name = "ダミー";
 }
}
```
```Main.java
public class Main {
 public static void main(String[] args) {
 Person p1 = new Person("タロウ");
  System.out.println("名前は" + p1.name + "です");
 Person p2 = new Person("ハナコ", 30);
  System.out.println("名前は" + p2.name + "で、年齢は" + p2.age);
 Person p3 = new Person();
  System.out.println(p3.name);
 } 
}
```
```結果.
名前はタロウで、年齢は25
名前はnullで、年齢は0
```

## 別のコンストラクタの呼び出し
```
this(引数);
```

```Person.java
public class Person{
 String name;
 int age;
 public Person(String name, int age){ // コンストラクタ①
 this.name = name;
 this.age = age;
 }
 public Person(){
 this("ハナコ", 30); // コンストラクタ①を呼び出すようにJVMに依頼
 }
}
```
```Main.java
public class Main {
 public static void main(String[] args) {
 Person p1 = new Person("タロウ", 25);
  System.out.println("名前は" + p1.name + "で、年齢は" + p1.age);
 Person p2 = new  Person();
  System.out.println("名前は" + p2.name + "で、年齢は" + p2.age);
 } 
}
```
```結果.
名前はタロウで、年齢は25
名前はハナコで、年齢は30
```
2024年5月 AIOps 定点観測

# 概要
AIOps の動向や学習のため、Google で AIOps を検索した結果を記録している記事です。

# 2024年5月1日の検索結果 (リスティング広告)

![スクリーンショット 2024-05-01 142014.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2345504/60f6c72f-450c-6c63-91b7-253e765a6c28.png)

* Dynatrace
* PureStorage
* Splunk
* ServiceNow

Dynatrace がトップで PureStorage と Splunk が続いています。

先月の結果はこちら --> [2024年4月 AIOps 定点観測](https://qiita.com/mkodera/items/918ac204ac66dc4b2dfb)

# 2024年5月1日の検索結果 (広告以外)

![スクリーンショット 2024-05-01 142119.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2345504/fdfaf7d1-9eae-d3a5-00c5-762a93c45954.png)

* HPE
* Splunk
* AWS
* IBM

3か月連続同じ順位でした。

先月の結果はこちら --> [2024年4月 AIOps 定点観測](https://qiita.com/mkodera/items/918ac204ac66dc4b2dfb)
VSCodeでRを使っている際の波線を消す方法について

# 概要
- VSCodeでRを編集していると波下線があちこちに発生する
- これはlintrという校正機能によるもので以下のような種類がある
https://lintr.r-lib.org/reference/linters.html#linters
- こちらの意図に沿わない校正などもあり，少々煩わしい時がある
- 以下の方法でオフにできる

# やったこと(どれでもいい)
### GUIの設定画面で機能をオフにする
- 以下の項目のチェックを外す
    - File(ファイル) > Preferences(ユーザ設定) > Settings(設定)
        - Extensions(拡張機能) > R > Lsp:Diagnostics
        - あるいは，「設定」の検索で「lsp」を検索するとでてくる

### 設定ファイルに書き込み
- 上部の検索バーに以下を入力する(あるいはCtrl+Shift+Pでコマンドパレットを呼び出して以下を入力する。)
`>Preferences: Open User Settings(JSON)`

- 以下を設定に書き込む。
`"r.lsp.diagnostics": false,`

### その他
- 全部オフではなく「1行80文字を超えたら波線」など，設定ごとに校正をオン・オフしたい場合は，設定ファイルを作る方法がある
- 以下など参照

https://stackoverflow.com/questions/69443818/how-to-control-the-behaviour-of-lintr-in-visual-studio-code
[SwiftUI] Combineを使用して、複数のPublisherな値の変更を監視

タイトルの通りSwiftUIで複数のPublisherな値を監視する実装を必要とするケースが発生したので、今回はその時に学んだ内容を書いていきたいと思います。

### 前提
コードを書いていく前に、なぜそのような実装が必要だったのかについて前提を簡単に書いておきたいと思います。
今回開発していたのがインスタライクな複数動画プレイヤーを縦に並べて表示することをやろうとしていて、その中で無限スクロール発火時にプレイヤー情報を5件ずつ取得して追加で表示するといったことを行なっていました。
ただ追加で表示する際に、ユーザー体験としてプレイヤーが表示されたらすぐに再生が始まるようにしたくて、この場合あらかじめ動画の読み込み状態が再生可能な状態になってから画面に表示する必要がありました。
ビデオの読み込み状態を監視するのはVideoPlayerViewModelというものが管理していて、これが動画プレイヤーごとに複数存在しています。なので無限スクロールが発火してから画面に追加分が表示される条件として、新たに生成される追加5件分のVideoPlayerViewModel全てが再生可能な状態になったということを確認する必要があったというのが今回の前提になります。

### Combineを使って監視を行う
VideoPlayerViewModelにはPublisherな値であるisVideoLoadedという動画の読み込み完了を表すフラグが存在します。なのでそれぞれのVideoPlayerViewModelが持つisVideoLoaded全てがtrueになることを監視するというのが今回実装したい内容になります。Combineについての詳細な説明は長くなるので省きますが、簡単にいうと非同期処理におけるデータフローを管理する仕組みのことです。実際のコードを見ていただけるとイメージしやすいかと思いますので、下記に記載します。

```swift
import Combine
import SwiftUI

class FeedVideosLoaderWatcher: ObservableObject {
  @Published var allVideosLoaded = false
  private var cancellables: Set<AnyCancellable> = []
  
  init(viewModels: [VideoPlayerViewModel]) {
    // 全ビデオのロード状態を監視するため、各Publisherの値を1つのストリームとして監視する
    let videoLoadPublishers = viewModels.map { $0.$isVideoLoaded }
    Publishers.MergeMany(videoLoadPublishers)
      .receive(on: RunLoop.main)
      // 全てのisVideoLoadedがtrueかどうかをチェックする
      .map { _ in viewModels.allSatisfy { $0.isVideoLoaded } }
      .sink { [weak self] allLoaded in
        if allLoaded {
          self?.allVideosLoaded = allLoaded
          // 全てのビデオがロードされたタイミングで、全ての購読をキャンセルする
          self?.cancellables.forEach { $0.cancel() }
          self?.cancellables.removeAll()
        }
      }
      .store(in: &cancellables)
  }
}

```
### コードの要点解説
まず監視対象である各viewModelのisVideoLoadedの値をまとめて取得し、Publisherな値としてまとめて配列に詰めます。
```swift
let isLoadedPublishers = viewModels.map { $0.$isVideoLoaded }
```
上記で取得した複数のPublisherな値を1つのPublisherとして管理するようにします。こうすることで全ビデオのロード状態を一つのストリームで管理することができるようになり、sinkで購読する箇所が1つにまとまるので、購読管理が簡素化され、リソースの使用が最適化されます。
```swift
Publishers.MergeMany(isLoadedPublishers)

// 下記のようにも書けるが、個別に購読することになり最適化されているとは言えず、コードも冗長になっている
for viewModel in viewModels {
      viewModel.$isVideoLoaded
        .sink { [weak self] isLoaded in
}
```
ここでは購読対象いずれかのisVideoLoadedが更新される => map内のallSatisfyがトリガーされ、全viewModelのisVideoLoadedがtrueかをチェック => その結果をsinkで受け取るような流れになっています。これにより最終的には全てのロードが完了したタイミングでallLoadedにはtrueが入ることになります。
```swift
.map { _ in viewModels.allSatisfy { $0.isVideoLoaded } }
.sink { [weak self] allLoaded in
```
最後に全viewModelのisVideoLoadedがtrueであることを確認できたら、全ての購読イベントをキャンセルしてリソースを解放します。
```swift
if allLoaded {
  // 全てのビデオがロードされた場合、全ての購読をキャンセル
  self?.cancellables.forEach { $0.cancel() }
  self?.cancellables.removeAll()
 }
}
```



## 終わりに
以上がCombineを使用した、複数のPublisherな値の変更を監視するやり方になります。実装方法は色々ありそうで、最適解を探していった結果今回のような実装になりました。もし上記以外で望ましいやり方がありましたら、ぜひコメント頂けますと有り難いです!
FontForge 日本語版トリセツ

今更感はありますが…

# 「トリセツ」データ格納場所
GitHub 
+ https://github.com/J1-takai/fontforge_docs_JA

# 背景
「馬酔木フォント」のグリフ拡張をしてみようかと思い、FontForgeにたどり着きましたが、
+ チュートリアル文書が膨大
+ （且つ）旧日本語版しか文書がない
+ （且つ　英語サイト版も内容が相当古そう）

という状況であったので、フォント作成学習はまたの機会にして、取り敢えず、アプリ現行版と比べつつ、項目ごとに分割編集したトリセツのようなものをpdfで途中まで作成してみました。

興味のある方がもし居れば、ご自由に参照してください。

# 補足
+ 完成時期は未定です。

以上
最先端で熱い！RyeによるPython環境の管理

Ryeを使って環境構築してみましょう。

Ryeは、Python開発者が必要とするさまざまな機能を1つにまとめた実験的なツールです。Pythonのインストールやパッケージ管理、仮想環境の管理などを自動化し、Ryeをインストールするだけで利用できます。詳細は「[Installation](https://rye-up.com/guide/installation/)」を参照し、基本的な使用方法については「[Basics](https://rye-up.com/guide/basics/)」を読んでください。

# 0.インストール
まずはこの[URL](https://github.com/astral-sh/rye/releases/latest/download/rye-x86_64-windows.exe)からRyeをインストールします。

# 1.Pathの追加
1. `Win`+`R`
1. `rundll32 sysdm.cpl,EditEnvironmentVariables`を入力
1. Pathをダブルクリックし、新規を押す
1. `%USERPROFILE%\.rye\shims`を入力
1. 再起動

# 2.環境設定
1. PowerShellを起動
1. 下記のコマンドを入力
```cmd
# Create a directory to store completion scripts
mkdir $PROFILE\..\Completions
echo @'
Get-ChildItem "$PROFILE\..\Completions\" | ForEach-Object {
    . $_.FullName
}
'@ | Out-File -Append -Encoding utf8 $PROFILE
# Generate script
Set-ExecutionPolicy Unrestricted -Scope CurrentUser
rye self completion -s powershell | Out-File -Encoding utf8 $PROFILE\..\Completions\rye_completion.ps1
```
を入力

# 3.アップデート
1. cmdを起動
1. `rye self update`を入力

# 4.環境構築
```cmd
rye init my-project
cd my-project
rye pin 3.10
rye sync
```

これで環境が構築される。
プロジェクト名やPythonのバージョンなどは良しなに変更する。

こんなに便利で有用なツール使うしかないでしょ！！
Wander Script

# はじめに

仕事で、下記のLowPolyAnimatedAnimalsを購入したのですが、
wander scriptというAIのような仕組みがついてきたので、それの覚書です。

https://assetstore.unity.com/packages/3d/characters/animals/low-poly-animated-animals-93089


# Wander Scriptとは


# 使い方

## AI Navigationのインストール

![スクリーンショット 2024-05-10 17.52.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/ce8cecaa-9bf0-5684-caba-6d033c68be92.png)

## Window -> AI から　ナビゲーションとナビゲーション(廃止)を選択

![スクリーンショット 2024-05-10 17.54.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/f9667d7d-c61a-55d8-6b27-eaaffb25369d.png)


![スクリーンショット 2024-05-10 17.54.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/ee8007b0-13b9-f84a-a576-c377fbb1cc70.png)

## 地面になるエリアを選択してベイクを押下

![スクリーンショット 2024-05-10 17.56.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/ace376ca-1ecd-706a-6670-8a3432d58571.png)

## 青くなった場所が地面になる

![スクリーンショット 2024-05-10 17.57.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/32b1fb85-f396-097b-8a05-e6ae0e6ab67f.png)




https://www.youtube.com/watch?v=WvBkwtqlNyI

![スクリーンショット 2024-05-01 14.07.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/ca2fcb16-36b1-0311-1986-664567f056f4.png)



# NavMesh Agent
NavMeshAgent コンポーネントは、相互に回避しながら目的地点に向かって進行するキャラクターの作成に利用できます。エージェントはナビメッシュを使ってゲーム世界の状況を判断し、それに基づき他のエージェントや障害物を回避することができます。経路探索や空間の判断は、ナビメッシュエージェントのスクリプト API によって行われます。

https://docs.unity3d.com/ja/2021.3/Manual/class-NavMeshAgent.html


![スクリーンショット 2024-05-01 14.07.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/28d7d502-847c-2f3b-dbb1-7b1efb6acddb.png)
Node.jsってなに？


## Node.jsってなに？

ブラウザ上での制限された環境でしか動かなかったJavaScriptを、PythonやRubyのようにパソコン上で動かせるのが
「 **Node.js**」になります。

Node.jsはWebサーバでもなく、Webフレームワークでもありません。

たんなる **JavaScript実行環境** になります。

Node.jsをインストールすると**node.exe** ができ実行できます。

Node.jsではJavaScriptでOSの機能にアクセスするプログラムを組むこともできます。

ブラウザ上で動作していたときはできなかった自由なファイルの書き込みやネットワーク通信なども行うことができます。


## Node.jsはサーバサイドの環境？


Node.jsは** サーバサイドの環境で動く** などとよく書かれています。

正しくは、**大量の同時接続をさばけるネットワークアプリケーションの構築** を目的に作られたJavaScript環境になります。

現在のWeb業界ではNode.jsは **クライアントのJavaScriptの開発環境** としても使われています。

なので、Node.jsは **サーバサイドの環境** としても、 **クライアントの環境** としても利用されているのが実態となっています。
TeratermでAIXのsmitを便利に使う+おまけ

## smitでESC+XXって面倒だよね？

ファンクションキーの代わりにShift+数字を押せばいいんですが、teratermのKEYBOARD.CNFを書き換えて便利に使おう。
```KEYBOARD.CNF をコメントにするところ抜粋
[VT editor keypad]
;PageUp key
;Prev=329
;PageDown key
;Next=337

[VT numeric keypad]
; F3 key
;PF3=61
; F4 key
;PF4=62

[VT function keys]
;F6 key
;F6=64
;F8 key
;F8=66
;F10 key
;F10=68
```

```KEYBOARD.CNF の最後尾に追加するところ
[User keys]
;PgUp for smit
User1=329,0,$1b$76
;PgDn for smit
User2=337,0,$16
;F3 for smit
User3=61,0,$1b$33
;F4 for smit
User4=62,0,$1b$34
;F6 for smit
User5=64,0,$1b$36
;F8 for smit
User6=66,0,$1b$38
;F10 for smit
User7=68,0,$1b$30
;Send Esc+\
User8=XXX,0,$1b$5c
```
これで上下スクロールと頻出ファンクションキーが使えるようになります。

おまけで書いた最下段のUser8はXXXに好みのキーの組み合わせをkeycord.exeから拾ってやると、viモードでの補完機能がショートカットで使えるようになります。
このXXXもファイルの何処かにあったらコメントにしてください。
行列積状態・テンソルトレイン分解

この記事では、行列積状態について自分用にまとめておきます。

# 量子状態と行列積状態
まず量子状態がどのように記述できたかを思い出しましょう。例えば、$S=\frac{1}{2}$スピン6個が相互作用する系を考えましょう。z方向のスピン固有状態を$|0>$と$|1>$と書くことにすると、この系の任意の状態は、

```math 
\begin{align*}
|\psi>&=\sum_{abcdef=0,1}c_{abcdef}|abcdef> \\
&=c_{000000}|000000>+c_{000001}|000001>+c_{000010}|000010>+\cdots
\end{align*}
```

係数$c_{abcdef}$は、$2^6=64$個の要素を持つテンソルとみなすことができます。ここで、係数$c_{abcdef}$を次のように見てみましょう。

```math 
\begin{align*}
c_{abcdef} = c_{a\big[bcdef\big]}
\end{align*}
```

右辺は$2^1×2^5$の行列という意味です。この行列を特異値分解すると、

```math 
\begin{align*}
c_{a\big[bcdef\big]}　= \sum_{\xi\xi'}U^{a}_{\xi}\lambda_{\xi \xi'}V_{\xi'\big[bcdef\big]}^{*}&=\sum_{\xi}U^{a}_{\xi}\sum_{\xi'}\lambda_{\xi \xi'}V_{\xi'\big[bcdef\big]}^{*}=\sum_{\xi}U^{a}_{\xi}D_{\xi bcdef} \\
\Big(D_{\xi bcdef}&:=\sum_{\xi'}\lambda_{\xi \xi'}V_{\xi'\big[bcdef\big]}^{*}\Big)
\end{align*}
```

となります。Dテンソルについても次のように特異値分解すると、

```math 
\begin{align*}
D_{\xi b\big[cdef\big]}=\sum_{\eta\eta'}&U^{b}_{\xi \eta}\lambda_{\eta \eta'}V_{\eta'\big[cdef\big]}^{*}=\sum_{\eta}U^{b}_{\xi \eta}F_{\eta cdef} \\
\Big(F_{\eta cdef}&:=\sum_{\eta'}\lambda_{\eta \eta'}V_{\eta'\big[cdef\big]}^{*}\Big)
\end{align*}
```

となります。同様にして次々に特異値分解すると最終的には、

```math 
\begin{align*}
c_{abcedf} = \sum_{\xi \eta \mu \nu \omega}U^{a}_{\xi}U^{b}_{\xi \eta}U^{c}_{\eta \mu}U^{d}_{\mu \nu}U^{e}_{\nu \omega}\lambda_{\omega}{V^{f}_{\omega}}^{*}
\end{align*}
```

となります(異なる脚を持つテンソルは別物)。以上より、6脚テンソルを、**3脚テンソルの縮約**で書くことができました。最終的に得られた状態は、

```math 
\begin{align*}
|\psi>=\sum_{abcdef=0,1}\sum_{\xi \eta \mu \nu \omega}U^{a}_{\xi}U^{b}_{\xi \eta}U^{c}_{\eta \mu}U^{d}_{\mu \nu}U^{e}_{\nu \omega}\lambda_{\omega}{V^{f}_{\omega}}^{*}|abcdef>
\end{align*}
```

となります。これを計算物理学では、**行列積状態**(Matrix Product State)と呼びます。試しに状態のノルムを計算してみましょう。得られたそれぞれの3脚テンソルはユニタリー性を満たすので、

```math 
\begin{align*}
<\psi|\psi>=\sum_{\omega}\lambda_{\omega}^{2}
\end{align*}
```

つまりノルムはその場所の特異値の2乗和で計算できます(量子論ではノルムは規格化されるので、$\sum_{\omega}\lambda_{\omega}^{2}=1$となるように取ります)。
上のように左の添字から順に特異値分解を繰り返したので、それぞれ添字の縮約次元は、

```math 
\begin{align*}
&\xi :2^1=2 \\
&\eta :2^2=4 \\
&\mu :2^3=8 \\
&\nu :2^4=16 \\
&\omega :2^1=2
\end{align*}
```

となり、中心に向かうほど指数的に増えてしまい、この分解に意味があるのか不思議に思います。しかし1次元量子系の低エネルギー状態(エネルギーギャップを持つ)は、縮約次元を少なく抑えても精度良く元の状態を記述できることが知られています。詳しい部分には踏み込みませんが、元の指数的に増える要素を少なくしてコンピュータに格納できるのです。また状態をMPSで持っておくことで、相関関数などの物理量を高速に計算できます。(テンソル分解業界では、多脚テンソルを上のように分解することをTensor-Train分解と言います)
ProxmoxをWake On LANで起動してみる。

本記事では仮想化基盤ProxmoxをWake On LANで起動させるまでの手順です。
大まかな手順としては以下の2つになります。
* BIOS側でWake On LAN を有効化
* OS側でWake On LANを有効化

# 環境情報
**システム構成**
| CPU | OS | NIC |
| ---- | ---- | ---- |
| Intel i7-6700 | Proxmox VE 8.2.2 x86_64 | enp0s31f6 |

**Motherboad**情報
```
# dmidecode -t baseboard
# dmidecode 3.4
Getting SMBIOS data from sysfs.
SMBIOS 3.0.0 present.

Handle 0x0002, DMI type 2, 15 bytes
Base Board Information
        Manufacturer: ASUSTeK COMPUTER INC.
        Product Name: H170 PRO GAMING
        Version: Rev X.0x
        Serial Number: 151261925701071
        Asset Tag: Default string
        Features:
                Board is a hosting board
                Board is replaceable
        Location In Chassis: Default string
        Chassis Handle: 0x0003
        Type: Motherboard
        Contained Object Handles: 0

Handle 0x0029, DMI type 10, 6 bytes
On Board Device Information
        Type: Video
        Status: Enabled
        Description:    To Be Filled By O.E.M.

Handle 0x0043, DMI type 41, 11 bytes
Onboard Device
        Reference Designation:  Onboard IGD
        Type: Video
        Status: Enabled
        Type Instance: 1
        Bus Address: 0000:00:02.0

Handle 0x0044, DMI type 41, 11 bytes
Onboard Device
        Reference Designation:  Onboard LAN
        Type: Ethernet
        Status: Enabled
        Type Instance: 1
        Bus Address: 0000:00:19.0

Handle 0x0045, DMI type 41, 11 bytes
Onboard Device
        Reference Designation:  Onboard 1394
        Type: Other
        Status: Enabled
        Type Instance: 1
        Bus Address: 0000:03:1c.2
```

# Wake On LANの有効化
### BIOS側の有効化
BIOSのwake up設定やwake on lan等の項目を探して、PCIeでの起動を有効化してください。

### OS側の有効化
#### ethtoolをインストール
```
# apt -y install ethtool
```

#### NIC名を確認
```
# ifconfig
```

#### Wake On LANの状態を確認
```
# ethtool enp0s31f6 | grep Wake-on:
    Supports Wake-on: pumbg
    Wake-on: d
```
Wake-on: dの場合は無効化されているので次の手順で有効化します。

#### 有効化する
```
 # ethtool -s enp0s31f6 wol g
```

#### 再度状態を確認
```
# ethtool enp0s31f6 | grep Wake-on:
    Supports Wake-on: pumbg
    Wake-on: g
```
Wake-on: gに変更されていることを確認してください。

#### 設定の永続化
再起動すると設定が元に戻り無効化されてしまうので、永続化されるようにしてください。
```
nmcli connection modify enp0s31f6 802-3-ethernet.wake-on-lan magic
nmcli connection up enp0s31f6
```

#### 再起動
```
# reboot
```

#### 再度状態を確認
```
# ethtool enp0s31f6 | grep Wake-on:
    Supports Wake-on: pumbg
    Wake-on: g
```

# クライント端末(Windows側)の設定

## 遠隔PC起動管理ツール
以下のサイトからnWOLをインストールしてください。
https://n-archives.net/software/nwol/

![スクリーンショット 2024-05-01 134311.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1066166/e4581dcb-49b8-1f0c-39f3-f5117e0e0dfb.png)

## nWOLを起動
![スクリーンショット 2024-05-01 134529.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1066166/af9de28d-ff3c-d486-895d-49722222058f.png)

赤枠の中にProxmoxで取得したホスト名、MACアドレス、IPアドレス、ネットマスクを入力して、追加をクリックしてください。
追加が完了したら右下のOKをクリックしてください。

## 赤い電源マークを押して起動すれば成功
![スクリーンショット 2024-05-01 135214.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1066166/3bcae1ca-570e-c603-f349-fcd1455eff94.png)
robloxでassistant その2

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



# 質問


テキストボックスを表示したい
# 回答

Roblox 作品にテキストボックスを表示するには、次の手順に従います。

1.Explorer ウィンドウで StarterGui を選択し、ScreenGui を追加します。
2.StarterGui の上にマウスを置き、＋ボタンをクリックします。コンテキストメニューが表示されます。
3.ScreenGui を挿入します。
4.新しい ScreenGui を選択し、TextBox を追加します。
5.ScreenGui の上にマウスを置き、＋ボタンをクリックします。コンテキストメニューが表示されます。
6.テキストボックスを挿入します。

これにより、画面にテキストボックスが追加されます。エクスペリエンスの美しさに合わせて、BackgroundColor3、BorderMode、Transparency、Rotation などのプロパティをカスタマイズできます。

パーツの面にテキストボックスを表示したい場合は、次の手順に従います。

1.Explorer ウィンドウで StarterGui を選択し、SurfaceGui を追加します。
2.StarterGui の上にマウスを置き、＋ボタンをクリックします。コンテキストメニューが表示されます。
3.ScreenGui を挿入します。
4.新しい SurfaceGui を選択し、TextBox を追加します。
5.SurfaceGui の上にカーソルを置き、＋ボタンをクリックします。コンテキストメニューが表示されます。
6.テキストボックスを挿入します。
7.TextBoxを表示したい部分にSurfaceGuiを飾ります。
8.[プロパティ] ウィンドウで、Adornee プロパティを選択します。カーソルが変わります。
9.Explorer ウィンドウでパーツを選択します。
TextBox が表示されない場合は、SurfaceGui の Face プロパティで別の面を選択してみてください。

ユーザーが TextBox を操作するときに TextBox が実行するアクションをスクリプト化することもできます。
たとえば、FocusLost イベントに接続して、ユーザーが Enter ボタンを押したとき、または TextBox の外側をクリックしたときに、TextBox の内容を印刷できます。スクリプトの例を次に示します。

local textBox = script.Parent
local function onFocusLost(enterPressed, inputObject)
    if enterPressed then
        print(textBox.Text)
    end
end
textBox.FocusLost:Connect(onFocusLost)

これがお役に立てば幸いです!さらにご質問がございましたらお知らせください。


以上。
Windows管理者アカウントでログインしているのにフォルダを削除できない



https://jp.minitool.com/news/need-administrator-permission-to-delete-folder.html


https://qiita.com/aoshirobo/items/f7aa2fcbe461beb202dd

上記の２つを読んだけどできなかった。
再起動も数え切れるくらいした。

なんか何回か再起動したりしたら消せた。

何も変更はしていません。

内部システムの更新にすこし時間がかかっただけなのかしら？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3334349/21a512ed-1e07-7315-3ea6-cb4d3654a64e.png)

これがでましたが、解決しなかったのでスルーして再起動したら普通にCommand Promptを通さずとも消すことができました
やっぱり再起動が大事。


# 公式アンインストーラーで解決
別途消したかったけど消し切れていなかったソフト。
システムの断片がどこかに残っていたようなので、公式アンインストーラーをサポートに連絡していただき、無事消すことができました。よかったです。
関数単体テスト（フロントエンドのテスト②）

※この記事はドラフト版です。

# 関数単体テストの~~実施~~ 準備
フロントエンドの言語がTypeScriptであるため
「Jest」というテストツールを使って関数のテストを行っていきます。

※３年前にとある案件でnode.jsでバックエンドの処理を作っていた際に
　後からJest導入が要件に追加され苦労した記憶。。。

## Jestのインストール
※node.jsがインストールされている前提です。
```bash
npm install --save-dev jest ts-jest @types/jest ts-node
```
## Jestの設定を行う
### スクリプトを追加する
```json:package.json
{
  "scripts": {
    "test": "jest"
  }
}
```
### Jestの設定ファイルを作成する
```bash
npx ts-jest config:init
```
次のファイルが作成される
```js:jest.config.js
/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
  preset: "ts-jest",
  testEnvironment: "node",
};
```
## Jestを使ってみる
前の手順までで、Jestの準備が終わりました。
実際にJestを試していきます。
### 関数の作成
Jestにかける用の関数を作っていきます。
```typescript:add.ts
export function add(x: number, y: number) {
  return x + y;
}
```
## テストコードの作成
先ほど作成した関数をテストするコードを書いていきます。
```typescript:add.test.ts
import { add } from "./add";

test("1 + 1 は 2", () => {
  expect(add(1, 1)).toBe(2);
});

```
## テストの実行
```bash
npm run test
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3743252/e5faa4c1-1664-a721-2140-10dadca3b22c.png)
下記の警告が表示
```bash
ts-jest[config] (WARN) message TS151001: If you have issues related to imports, you should consider setting `esModuleInterop` to `true` in your TypeScript configuration file (usually `tsconfig.json`). See https://blogs.msdn.microsoft.com/typescript/2018/01/31/announcing-typescript-2-7/#easier-ecmascript-module-interoperability for more information.
```
## TypeScriptの設定ファイルの作成
```bash
npx tsc --init
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3743252/2423b26a-da0f-f57c-b103-e2d1139b2a81.png)

## 再度テストの実施
```bash
npm run test
```

警告が消えた
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3743252/6ad798ac-c46b-4a0a-3e18-f9d671377bff.png)


## VSCodeのjestの拡張機能のインストール
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3743252/f38b18bc-bfe3-c778-cea9-6515f1fefaa7.png)
Runボタンを押すと、該当のテストケースだけ実行してくれる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3743252/918be67a-9cd0-1f98-b348-2b6ba56517ec.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3743252/72ca3d56-4eda-97f7-589e-6098bbc1b4d7.png)

## まとめ
テストの実施の記事のつもりでしたが、準備だけで終わりました。
Jestの設定が初期値なので不安がありますが、動いているのでOKとします。
今後、テストを行う中で不具合がでたら対応する方向で行きます。

次の予定は加算だけでなくいくつかの関数を書いて、関数毎にテストを書いていく予定です。