OmniAICreator/Qiita-1.07M huggingface dataset:
EVE-NG スナップショットの変更

備忘録
EVE-NGのLinuxの設定して、最後にスナップショットでの変更を反映させてベースイメージを更新する操作

差分を探します。
```
root@eve-ng:~# find / -name  "virtioa.qcow2"
/opt/unetlab/tmp/0/fd0c6541-cda9-4cdc-8b56-b242b807fb54/2/virtioa.qcow2
/opt/unetlab/tmp/0/fd0c6541-cda9-4cdc-8b56-b242b807fb54/5/virtioa.qcow2
/opt/unetlab/addons/qemu/linux-SP2/virtioa.qcow2
/opt/unetlab/addons/qemu/linux-SP1/virtioa.qcow2

#qemu-img commit -f qcow2  /opt/unetlab/tmp/0/fd0c6541-cda9-4cdc-8b56-b242b807fb54/5/virtioa.qcow2
```
これで、変更をすべて親イメージに適用する事が出来ます。
ローカル環境に溜まった不要なブランチを一括で削除したい時の解決策

## はじめに

マージ済みブランチを削除せず溜まってしまっているエンジニア向けに、ローカル環境から一括で削除する方法をまとめます。
<br>

記事のとおりにコマンドを実行すれば、ローカル環境に存在するブランチのうちマージ済みのものだけを一括で削除できるはずです。

## 問題

ローカル環境にマージ済みのブランチがかなり溜まっていたため、削除して見通しをよくしたかったです。
<br>

1つずつ`git branch -d branch-name`とすれば削除できますが手間なので、一括で削除できる方法を探していました。

## 解決策

結論として、次の流れでコマンドを実行すればマージ済みのブランチを一括で削除できます。
<br>

```bash
$ git switch develop  # ベースブランチへ移動
$ git branch --merged | grep -v "\*" | xargs git branch -d
```

### コマンドの説明

- `git branch --merged`: 現在のブランチにマージ済みのローカルブランチを一覧表示
- `grep -v "\*"`: 出力結果から現在のブランチ（`*`が付いているブランチ）を除外
- `xargs git branch -d`: フィルタリングされたブランチを削除

### 注意点
- **未マージのブランチを削除しない**: `-d`オプションを付与してるため、未マージのブランチは削除されない
- **現在のブランチを削除しない**: `grep -v "\*"`で現在のブランチを除外している

### 未マージのブランチも含めて強制的に削除したい場合
マージされていないブランチも含めて強制的に削除したい場合は`-D`オプションを付与します。
<br>

```bash
$ git branch --merged | grep -v "\*" | xargs git branch -D
```
<br>

ただし重要なブランチを誤って削除しないよう注意が必要です。

### 補足：`xargs`コマンドについて

`xargs`は前のコマンドの出力を引数として次のコマンドに渡すためのコマンドです。
<br>

#### 使い方の例

以下の例は`コマンドA`の出力結果を`コマンドB`の引数として渡すことを意味しています。
<br>

```bash
$ コマンドA | xargs コマンドB
```

#### 今回の例

`git branch --merged`で得たマージ済みブランチから`*`が付いているブランチ以外を、`xargs`で`git branch -d`に渡して削除しています。
<br>

```bash
$ git switch develop  # ベースブランチへ移動
$ git branch --merged | grep -v "\*" | xargs git branch -d
```

## おわりに

`git`コマンドと`grep`、`xargs`を組み合わせることで、ローカルブランチの一括削除を効率的に行うことができました。
<br>

基本的なコマンドでも、組み合わせ次第で便利な操作が可能です。
<br>

今後もコマンドの活用方法を探求していきたいと思います。
ChatGPTにDrawioをかかせて、Vscodeで調整する

# 目的
画面遷移図を作成するにあたって、DrawioをChatGPTに書かせて楽をすることを目的とする。

# 方法
VscodeでDrawioの拡張機能をインストールしておき、ファイルを編集できるようにしておく。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691111/9afc44e1-8966-fd82-9825-c723f0c8c0d2.png)

エクスプローラービューにdrawioファイルを右クリックする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691111/57a53915-7775-83e6-9161-45109b34e8c0.png)

Formatを選択するとXMLコードが表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691111/bf290ecc-6eee-ad8c-a2ff-af5826338eba.png)


これをChatGPTに渡して修正してもらうように指示すればOK。
ただし、矢印の長さなどの微調整は必要。

# 所感
これでいろんな図形がかけそうなので、いろいろ試してみようと思います。
これから使って気になったことがあれば追記します。

追記：画面数が多くなる要望には対応できませんでした。。。
Rover製作16 EspressoFrameの電装品（タワー部）の用意

# 概要
タワー部の電装品の用意やケーブルの製作をします。

# 全体像
下記図の「上部モジュール」と記載のある部分の電装品にんついて当記事で説明します。

![espresso_frame_elec_v2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254442/fa978fa1-7cd2-ad06-90f9-691c36429ef4.png)

# 電源系
## 電源ハブ
HolybroのPowerDistributionBoardです。
タワーモジュールの各電源への配線に使います。
![XT60_XT30_PDB.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254442/4c1b4b13-c32b-30c7-7b40-16d5fc5bc39f.png)

## 電源ケーブル
移動部のPDBとタワー部のPDBをつなぐ、両端がTX60の1m程度のケーブルです。

# サーボ関連
## サーボ(STS3215)
RealSense用のパンチルト機構に使用します。STS3215を2つ使用します。
1個につき10cm程度のサーボケーブルが付属しています。
（コネクタは「Molex5264」と少し珍しいものですが千石で売っています）

![STS3215.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254442/2e8cd717-af1d-dab3-c032-e23945224869.jpeg)

## サーボ用インターフェイスボード(FE-URT-1)
STS3215用のUSB-シリアル基板です。
電源はねじ端子で接続します。

![FE-UR-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254442/da1a4a51-6213-3825-efbc-a970759cf400.png)

## サーボ電源ケーブル
バッテリーの18V電源を6Vにします。
以下のようなケーブルタイプのDCDCが便利です。
TX30-(IN)DCDC(OUT)-剥き線 と接続します。

# HDMIモニター関連

## HDMIモニター
以下のような7inchモニターがちょうど収まります。裏にM4ねじ穴が点いているものを選んでください。

![monitor_7inch.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254442/1e63c939-96df-1b00-7a9b-4345c2a403e5.jpeg)

## HDMIモニター電源ケーブル
バッテリーの18V電源を12Vにします。
モニターとはDCコネクタ(2.1mm)で接続します。

# タブレット関連

## Androidタブレット
「fireHD8Plus」を使います。
NUCとの接続はUSB経由のEtherで行います。このタブレットはハブをかませてもEtherと接続が両立しないので、充電は後述のQiで行います。

## Qi充電器(Anker PowerWave 10)
fireHD8Plusを充電するために使用します。

![anker_qi_charger.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254442/4bf3366b-eeed-1a31-e78e-908b8995b8bd.png)

## USB電源ケーブル
https://www.amazon.co.jp/gp/product/B07GT372VJ
バッテリーの18VをUSB電源に変換するものです。
入力側はTX30のコネクタをつけます。

## USB-Ether変換
リンク:https://www.amazon.co.jp/dp/B07RW4P61B

USB type-CとEtherの変換アダプタです。

![ETG-US3TC.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254442/745a47e2-5fb5-12bc-5824-d86b221bacba.jpeg)

# 他

## 広角カメラ(CMS-V43BK)
リンク:https://www.amazon.co.jp/dp/B07JN3NYC5

広角のWebカメラです。

![CMS-V43BK.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254442/a1f373cd-65ad-38c1-da90-8884e5175b20.png)

## USBハブ(EDC-GUA3H2-B)
リンク:https://www.amazon.co.jp/dp/B09TD2YPTC

Ether付きのUSBハブです。

![EDC-GUA3H2-B.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254442/ae108ddf-3672-8057-8db5-154b92dc4856.jpeg)
GAS Googleスプレッドシートの Query で値が取得できない！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680230/8bb94fe1-feff-584c-b08a-d087a418d44e.png)

# はじめに
今回は、GAS で Query を利用した際にハマってしまった内容です。
下部の”参考”に記載させて頂いた投稿により解決する事ができました。
次にハマった方の”検索”に少しでもヒットすればと投稿します。

# ざっくり処理
1. Slack Bot から値を入力・選択して、Google Apps Script へリクエスト
1. Google Apps Script で、対象の Google スプレッドシートから Query で別シートに抽出
1. 抽出結果を処理して、Slack Bot へ返却

# 問題
Google スプレッドシートで Query の処理を行っていたのですが、特定の"文字列"項目だけ値が取れない

ただ、
- 裏の処理で固定文字を入れているレコードは"文字"でも、Query で取得できる
- 対象項目の値を"文字" -> "数値"に手動で変更すると、Query で取得できる

# 原因
[Google sheet Query Function Returns blank result from cell with data](https://stackoverflow.com/questions/29735765/google-sheet-query-function-returns-blank-result-from-cell-with-data)

**文字列と数値の混在する列で、文字列が少数派だと勝手に空白セルに変換してしまうらしい。**

→　えっ！？　これはバグではないでしょうか？ > Google さん　

# 解決策
Query を修正。
```
=QUERY(ARRAYFORMULA(TO_TEXT('シート1'!A:X)),"select Col1... where Col1...")
```
- TO_TEXT : 対象を全て文字に変換
- ARRAYFORMULA : 配列数式に変換

### ポイント
- Query 内で利用する項目が、"A" -> "Col1" に変わるので注意！
- 全部文字になるので、日付オブジェクトとかの項目は個別に型変換が必要になります



# おわりに
stackoverflow に数年前から記載されていて、今も発生するという事は**仕様**なんでしょうね。。。


---
**参考（感謝）**
- [GoogleスプレッドシートのQuery関数で結果が空になる謎仕様と回避策](https://qiita.com/Shinoda_Naoki/items/d73e28a8a99fdc5ec1f5)
- [Google sheet Query Function Returns blank result from cell with data](https://stackoverflow.com/questions/29735765/google-sheet-query-function-returns-blank-result-from-cell-with-data)
P2V(Physical to Virtual)

備忘録

　2008年製の東芝 かSatellite K30でCentOS7で、とあるシステムが動作しており、ハードの故障を考慮して、P2V化しました。K30のスペックは、CPU Core2Duo(P8400) 2.26GHz/メモリ 3GB/HDD 80Gです。
　オフラインでのdd化を検討しましたが、駄目元で、まず、オンラインで作業を実施してみました。

# ■オンライン作業
# Step1.不要プロセスの停止
　不要プロセスを停止します。

# Step2.ディスクの確認
　ディスクデバイスが /dev 以下にあることを確認します。通常、ディスクは /dev/sda や /dev/vda といった名前で表示されます。ディスクの状態を確認するには、以下のコマンドを使用します。
 ```
#lsblk
NAME            MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda               8:0    0 74.5G  0 disk
tqsda1            8:1    0    1G  0 part /boot
mqsda2            8:2    0 73.5G  0 part
  tqcentos-root 253:0    0 47.5G  0 lvm  /
  tqcentos-swap 253:1    0  2.9G  0 lvm  [SWAP]
  mqcentos-home 253:2    0 23.2G  0 lvm  /home
```
# Step3.dd コマンドでディスクイメージの作成
  sshサーバを用意してデータを転送します。今回、80GバイトのDiskで100Mbpsの回線で2時間かかりました。圧縮しながら転送する方法も考えましたが、CPUが貧弱なので、ベタ転送しました。
転送量は、sshサーバ側でlsコマンドで確認します。
```
#dd if=/dev/sda  | ssh user@192.168.xx.xx "dd of=/tmp/ディスクイメージ.img"
```
# Step4.qcow2変換
　ディスクイメージのままでは、サイズが大きいので、qcow2形式に変換します。
```
#qemu-img convert -f raw -O qcow2 変換前ファイル名.img 変換後ファイル名.qcow2
```
# Step5.イメージ圧縮
　そのままではサイスが大きいので、イメージを圧縮します。
```
#qemu-img convert -c -f qcow2 -O qcow2 圧縮前.qcow2 圧縮後.qcow2
```
今回は、オンライン作業が出来ましたが、オフラインで作業する方法を記載しておきます。

# ■オフライン
# Step1. CentOS 7 レスキューモードで起動
・CentOS 7 インストールメディアを用意します。
・サーバーを再起動し、BIOS 設定で USB/DVD から起動するように設定します。
・インストールメディアから起動し、以下の画面が表示されたら「Troubleshooting」を選択します。
```
Install CentOS 7
Test this media & install CentOS 7
Troubleshooting
```
# Step2. レスキューモードでシステムのマウント
画面の指示に従って進むと、以下のような選択肢が表示されます。
```
1) Continue (mount your partitions under /mnt/sysimage)
2) Read-Only mount (mount your partitions under /mnt/sysimage in read-only mode)
3) Skip (skip to shell)
```
1 を選択して、パーティションを /mnt/sysimage にマウントします。
次に、ルート環境に入るため、以下のコマンドを実行します。
```
#chroot /mnt/sysimage
```
# Step3.ディスクの確認
　ディスクデバイスが /dev 以下にあることを確認します。通常、ディスクは /dev/sda や /dev/vda といった名前で表示されます。ディスクの状態を確認するには、以下のコマンドを使用します。
```
#lsblk
```
# Step4.EthernetにIPアドレスを設定
```
#ip link show
#ip addr add 192.168.1.100/24 dev eth0
#ip link set enp0s3 up
```
# Step5.オンラインのStep3以降を実施します。

　転送したイメージですが、そのままでは起動できず、-cpu core2duoを指定しました。また、バスが、virtioでは起動中にハングする為、sataにしたところ正常に起動できました。
トランザクション分離レベル（ISOLATION LEVEL）について

データベーススペシャリスト試験の勉強をしていて初めて出会った「トランザクション分離レベル（ISOLATION LEVEL）」について、内容を忘れないよう、学んだ点を整理しておこうと思います。

## 前提知識
### 共有ロック
他のトランザクションからの対象行の参照が可能なロック。変更は共有ロックの解放待ちとなる。

### 占有ロック
他のトランザクションからの対象行の参照・変更ともに不可となるロック。占有ロックが解放されるまで他のトランザクションは参照・変更を待つ必要がある。

## トランザクション分離レベル（ISOLATION LEVEL）
複数のトランザクションが同時に実行される際に、互いにどのように影響を及ぼすかを制御するための設定のこと。

主に4つの分離レベルがあり、それぞれ異なる特徴を持っています。

### READ UNCOMMITTED
名前の通り、他のトランザクションが未コミットのデータも読み取る方式。
- データ参照時は**共有ロックや占有ロックを無視して**読み取る
- データ変更時に占有ロックを掛け、トランザクション終了時に解放する

データ参照時に共有ロックや占有ロックを無視するため、他のトランザクションでまだコミットされていないデータを読み取れてしまう。

これをダーティリードという。

:::note info
ダーティリード
他のトランザクションで更新された"コミット前"のデータを読み込んでしまうこと。
:::

### READ COMMITTED
名前の通り、他のトランザクションがコミットしたデータのみを読み取る方式。
- データ参照時に共有ロックを掛け、**参照終了時に**解放する
- データ変更時に占有ロックを掛け、トランザクション終了時に解放する

データ参照時に占有ロックを無視しないためダーティリードは起きない。

また、データ参照時にかける共有ロックは参照処理が終了したらすぐロックを解放するため、解放後は他のトランザクションでそのテーブルを更新可能となってしまう。

これにより、例えば、トランザクションAにおいて、とあるテーブルの同じ行を複数回参照する場合、1回目の読み取り処理と2回目の読み取り処理の間で、他のトランザクションBが同じ行に対し更新処理を行うと、1回目と2回目で読み取れるデータが異なる可能性がある。

これをノンリピータブルリードという。

:::note info
ノンリピータブルリード
**同じデータ**を2回リードしたときに値が異なる可能性のある読み方のこと。
1回目と2回目の間に別のトランザクションによりデータが変更され、不整合が発生する可能性がある。
:::

### REPEATABLE READ
名前の通り、繰り返し読み取っても不整合が発生しない方式。

- データ参照時に共有ロックを掛け、**トランザクション終了時に**解放する
- データ変更時に占有ロックを掛け、トランザクション終了時に解放する

共有ロックをトランザクション終了時に解放するため、ノンリピータブルリードは起きませんが、ファントムリードが発生する可能性があります。

:::note info
ファントムリード
1回目と2回目のリードの間に、他のトランザクションによってデータが追加されてしまう読み方のこと。
1回目にはなかった幻＝ファントムのデータが発生し不整合になる可能性がある。
:::

ファントムリードはノンリピータブルリードと似ているが、ノンリピータブルリードは1回目と2回目で参照した同じ行に対してデータの不整合が発生するのに対し、ファントムリードは参照していない他の行にデータの不整合が発生することを指している。

データ参照時に参照する行に対して共有ロックをかけトランザクション終了時に解放するため、トランザクションを解放するまでは参照している行に対して他のトランザクションから更新されることはなくなりますが、その他の範囲への行についてはロックはかけていないため追加可能となっている。

### SERIALIZABLE
名前の通り、トランザクションが完全に直列化されたかのように振る舞う方式。
- データ参照時に、**クエリでアクセスする行やインデックスの範囲に対して**共有ロックまたは意図的ロックを取得し、トランザクション終了時に解放する
- データ変更時は占有ロックを使用し、トランザクションが終了するまで解放しない

「REPEATABLE READ」までは、読み取る行単位に共有ロックをかける方式ですが、「SERIALIZABLE」ではアクセスする範囲に対してロックを取得する点が他と異なる。

ロックを掛ける範囲については詳しく調べられていないのですが、イメージとしては表ロックに近いレベルでのロックを取得するんだと思う。

## まとめ
4つの分離レベルについて整理しましたが、最後にまとめると表のようになる。

| ISOLATION LEVEL | ダーティリード | ノンリピータブルリード | ファントムリード |
|:-:|:-:|:-:|:-:|
| READ UNCOMMITTED  | ○  | ○  | ○ |
| READ COMMITTED  | -  | ○  | ○ |
| REPEATABLE READ  | -  | -  | ○ |
| SERIALIZABLE  | -  | -  | - |

これを見ると、データベースの設定は分離レベルが一番高い「SERIALIZABLE」にすればいいじゃん、と思ってしまいますが、分離レベルを上げれば上げるほど、ロックの解放待ちが発生しやすく、一概に分離レベルを上げればいいというものでもない。

一般的なWebシステムの分離レベルとしては「READ COMMITTED」を選択し、同じデータに対する読み取りの一貫性が必要な場合は「REPEATABLE READ」を設定するのがいいのかなと思う。

以上
Metavision Studio使用時のレコーディングエラー

# 問題
Metavisionsdkを用いてSilkeyEvcam(VGA)での撮影を行おうとしたところ
次のようなエラーが出て録画ができない. 
```
C:\Program Files\Prophesee>
[SERVER] - stderr - [SDK][STUDIO]
------------------------------------------------
Metavision SDK Driver exception

Error 103004: Could not open file 'C:\Users\test\OneDrive\繝峨く繝･繝｡繝ｳ繝・metavision\biases\biases.bias' for writing. Failed to save biases.
Could not open file.
------------------------------------------------
[SERVER] - stderr - [SDK][STUDIO] Event stream decoding violation NonMonotonicTimeHigh
```

# 解決策
%USERPROFILE%\AppData\Roaming\Metavision Studio\config.json内のパスをすべて英字の適当な場所に変更する.

# 補足
デフォルトだとonedriveがuninstallされていない場合にはOneDriveのドキュメントの下にデータを作成するらしく,そこで日本語が使われていることがエラーの原因であった. 
その他の原因もあるらしいのでその場合にはCenturyarksのサイト等も参考にするとよいことが分かった.
<https://centuryarks.com/faq/metavision-studio-%e3%82%92%e8%b5%b7%e5%8b%95%e3%81%99%e3%82%8b%e3%81%a8%e3%82%a8%e3%83%a9%e3%83%bc%e3%81%8c%e5%87%ba%e3%81%a6%e3%82%ab%e3%83%a1%e3%83%a9%e3%81%8c%e8%aa%8d%e8%ad%98%e3%81%95%e3%82%8c/>
HTTPのメソッドを復習したい


HTTPメソッドについて整理していきたいと思います。

## HTTP Request
3つの要素で構成される

- リクエストライン　```POST / HTTP/1.1```
- ヘッダー　```Host: localhost:3030```, ```User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/113.0```
- ボディ　```{"name":"iyo", "age":16}```

#### リクエストライン【主要なメソッド】
- GET: リソースの取得
- POST: リソースの作成
    - リクエスト成功時は201で新しいリソースのURIをLocationヘッダーに設定
- PUT: リソースの更新、作成（あれば丸ごと更新、なければ作成）
    - リクエスト成功時は201で新しいリソースのURIをLocationヘッダーに設定
    - または200を返す（更新時）
- PATCH: リソースの更新、作成（あれば部分更新、なければ作成）
     - リクエスト成功時は200を返す
- DELETE: リソースの削除
     - リクエスト成功時は200を返す

#### 冪等性とは？
同じ操作を繰り返しても同じ結果になること
##### 冪等性あり
- GET: 何度データを取得しても同じ
- PUT: あれば更新、なければ更新されない状態が維持される

##### 冪等性なし
- POST: リソースの作成をした際に、複数リソースが新規作成される可能性あり
- PATCH: リソースの更新、作成（あれば更新、なければ作成）
- DELETE: リソースの削除


## 参考
- [Web APIとは？【初心者向け】基礎知識を徹底解説](https://www.dal.co.jp/column/r-webapi/)
- [HTTP メッセージ](https://developer.mozilla.org/ja/docs/Web/HTTP/Messages)
- [httpリクエストヘッダの一覧](https://apidog.com/jp/blog/http-request-headers-summary/)
- [POSTとPUTの違いを説明できないエンジニアがいるらしい](https://qiita.com/Sicut_study/items/45372a38592fbbbc051a)
- [冪等性とは「同じ操作を何度繰り返しても、同じ結果が得られる性質」のこと](https://qiita.com/suin/items/316cb8aaf8dfcf11abae)
- [主要なステータスコード](https://qiita.com/TaaaZyyy/items/241ab17219bd0cc04504)
- [HTTPとRESTの基本 『網羅版：HTTPメソッドとレスポンスコード』](https://qiita.com/yoshitaro-yoyo/items/03f0296f4ba7011d654f#1-6-http%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89getpostputdelete)
- [RESTful API設計におけるHTTPステータスコードの指針](https://qiita.com/uenosy/items/ba9dbc70781bddc4a491)
Todo管理アプリ「Todoカンリ」にWebサービスの基本機能を追加する

# 初めに

https://qiita.com/opatu07/items/13ebcd6071a3d7893d5d

この記事でHTML,CSSの使い方はある程度わかったので
Webサービスの基本的な機能を作れるようになりたいと考えました。
なのでその設計を行います。

# 追加する機能
## 認証系
- 会員登録
- ログイン
- ログアウト

## CRUD系
- 新規登録
- 一覧表示
- 詳細表示
- 編集機能
- 削除機能

# プログラミング言語
- PHP
- MySQL

# なぜこの開発を行うのか
今回はLaravelなどのPHPのフレームワークを使用せずに開発を行います。
フレームワークを使用しない理由はWebシステムの仕組みを理解して開発を行うことが大事だと考えたからです。
もし開発チームに入った時に一覧機能の修正を依頼されたとします。でもフレームワークに頼った開発しかしていない場合大量のソースコードの中でどこをどのように修正するべきかがわからないので開発をすることができません。
なので今回はPHPのみを使用してサービスの機能の根本的な理解を目的とした開発をしていきます。
以前参加したインターン先の入社課題としてもこのような課題があったためサービスの機能の根本的な理解が大切なのだと考えました。

# ユースケース図の作成

![use-case2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682713/ddc53dd4-1037-af56-d3ca-3f3f540f7f7d.png)

# 画面遷移図の作成

![seni2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682713/1a5821ef-2c00-c0cf-79bd-b20c21b4e76d.png)

# ワイヤーフレームの作成

![スクリーンショット 2024-11-10 17.41.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682713/59e637b2-31d3-e1b6-8e6c-aacd74b7e42e.png)


![wire_flame_2_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682713/dac8ab23-af15-7968-3c73-979a1aa1429e.png)

![wire_flame_2_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682713/c25f4a2b-bf2c-223e-f243-868a5ebd5542.png)

# 作成期間について
html,cssで作成していない画面の作成・・・1日
phpの導入・・・2日
SQLの導入・・・2日
予備日・・・2日
で考えています。
前回はリスケがうまくできていなかったので今回は意識して予備日を設定しています。
この期間内に終わらせられるようにします。
【AppStream 2.0】PCのスペック気にしない！AppStream 2.0ってなに？おいしいの？から初学習


## 百聞は一見に如かず、AppStream2.0触ってみよう！
**実はすぐにデモ触れれます
「ああ、なるほどねざっくりわかったわ」ってなっていただけると思います。**

[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806193/8080c9be-84d6-4139-8c37-fea56b07ba3e.png)](https://aws.amazon.com/jp/appstream2/try-sample-applications/)


https://aws.amazon.com/jp/appstream2/try-sample-applications/

---
### 一言要約

:::note info
めっちゃ大雑把いえば、
**AppStreamはアプリだけ配信**するマネージドサービス。
ちなみに**workspaceaはデスクトップ環境（VDI）ごと配信**するサービスでよく比較される
:::





## もうちょい詳しく

Amazon AppStream 2.0 は、AWS が提供する「クラウド上で動作するアプリケーションの画面をユーザーに配信する」ためのサービスです。このサービスを使うと、自分のPCやタブレットでアプリを操作しているように見えますが、実際のアプリケーションはクラウドで実行されています。  <font color="red">**つまりスペックが微妙なPCでも画像を配信してもらってるだけなので、いい感じにアプリを動かせるということです。**</font>

企業や教育機関、ソフトウェアベンダー（ISV）など、さまざまなシーンでの活用が期待されています。例えば、以下のようなメリットがあります。

- **高度なアプリも使える**：グラフィックや設計ツールなど、重いアプリもクラウドで実行でき、デバイスの性能に影響されません。
- **柔軟な料金体系**：従量課金制なので、使った分だけ支払い、コスト管理が容易です。
- **使い捨てセッション**：非永続的なセッションにより、毎回新しい環境で安心して利用できます。


### AppStream 2.0 と WorkSpaces の違い
AWS の「Amazon WorkSpaces」との違いも気になるかもしれません。WorkSpaces が仮想デスクトップ環境の提供に特化しているのに対して、AppStream 2.0 は一時的なアプリの利用に最適です。以下の表で主な違いをまとめてみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806193/aa6ffbe2-184f-869b-9762-964d47105c82.png)



| 項目                   | AppStream 2.0          | WorkSpaces                  |
|------------------------|------------------------|-----------------------------|
| **目的**               | アプリケーション配信     | 仮想デスクトップ環境の提供  |
| **利用シーン**         | 一時的なアプリ利用       | 常時利用のデスクトップ環境  |
| **対応OS**             | Windows Server、Amazon Linux | Windows 10、Ubuntu など |
| **料金体系**           | 従量課金                | 月額固定または従量課金      |
| **モバイル対応**       | ブラウザで iPad/Android 対応 | 専用アプリが必要           |
| **Microsoft Office** | 利用不可               | 利用可能                   |



### Amazon AppStream 2.0 の使い方と効果
AppStream 2.0 は、特定のアプリに限定したリモートアクセス環境を提供したい場合に便利です。たとえば、以下のようなケースで効果的に活用できます。

- **一般企業**：一時的に使うグラフィックアプリや、リモートアクセスが必要な業務ソフトを社員に提供し、ハードウェアの更新頻度を抑えられます。
- **教育機関**：学生が仮想ラボとして利用し、自宅や教室から特定のアプリで学習可能に。
- **ソフトウェアベンダー（ISV）**：クラウド上で体験版を提供することで、ユーザーがインストール不要で試用でき、導入までのハードルを下げます。


### Amazon AppStream 2.0【AWS Black Belt】
amazon公式からも詳細な説明もあります！

<iframe width="560" height="315" src="https://www.youtube.com/embed/sBnPKz-pAVA?si=UayUIVC78coTvsBd" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

## まとめ
Amazon AppStream 2.0 は、クラウド上でアプリケーションを実行し、その画面をユーザーのデバイスに配信する便利なサービスです。非永続的で柔軟な利用が可能なため、短期的な利用ニーズにも対応。例えば、個人用PCでは重すぎるアプリケーションも、クラウドで快適に利用できます。今すぐ AWS の公式サンプルアプリケーションで実際の体験も可能です。

クラウド配信の新しい選択肢として、ぜひ検討してみてください！
Excel・Googleスプレッドシートで時間差を計算！TIMEVALUE

### TIMEVALUE関数とは？

TIMEVALUE 関数は、文字列形式で入力された「時間」をスプレッドシートが認識できる時間値（数値形式）に変換する関数です。これにより、時間同士の引き算や加算が簡単に行えるようになります。

### 基本的な使い方

TIMEVALUE(時間の文字列) の形式で使用し、時間を0〜1の小数値（1日=1）に変換します。


例：8時30分15秒から17時45分50秒の時間差を計算する
セルA1：08:30:15
セルB1：17:45:50

```scss
=TIMEVALUE(B1) - TIMEVALUE(A1)  
```

この計算結果は 0.38356 となります。これは 1日（24時間）を1とする小数形式なので、これを時間に変換する必要があります。

#### 変換方法

- 日

```scss
=TIMEVALUE(B1) - TIMEVALUE(A1)  
```

- 時間

```scss
=(TIMEVALUE(B1) - TIMEVALUE(A1)) * 24
```

- 分
```scss
=(TIMEVALUE(B1) - TIMEVALUE(A1)) * 24 * 60
```

- 秒
```scss
=(TIMEVALUE(B1) - TIMEVALUE(A1)) * 24 * 60 * 60
```

### まとめ
TIMEVALUE 関数を使うことで、文字列形式の時間をスプレッドシートが認識できる数値に変換し、計算が可能になります。分や秒を含む複雑な時間計算も簡単に行えます。


参照

https://support.google.com/docs/answer/3267350?hl=en
https://support.microsoft.com/ja-jp/office/timevalue-%E9%96%A2%E6%95%B0-0b615c12-33d8-4431-bf3d-f3eb6d186645
[Docker] コンテナが起動しない時の対応

Dockerを使っているとコンテナが起動すらせず、中がどうなっているか確認できないことがある。
```Dockerfile
# ASP.NET Core 8.0のランタイムイメージを使用
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
WORKDIR /app
EXPOSE 8080

# .NET SDK 8.0を使用してビルド環境を構築
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY ["ProjectTest.csproj", "./"]
RUN dotnet restore ProjectTest.csproj

# ソースコード全体をコピーし、リリースビルドを実行
COPY . .
RUN dotnet publish -c Release -o /app/publish
ENTRYPOINT ["tail", "-f", "/dev/null"] 

# ランタイムイメージに公開済みビルドをコピー
FROM base AS final
WORKDIR /app
COPY --from=build /app/publish .
ENTRYPOINT ["dotnet", "ProjectTest.dll"]
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2841371/6508f214-12cc-c3d7-f2e9-b4ce6b4d0020.png)

この場合、ENTRYPOINTを以下のコードに変更する
```Dockerfile
ENTRYPOINT ["tail", "-f", "/dev/null"] 
```
コンテナが起動するので、以下のコマンドをターミナルで実行するとコンテナ内に入ることができる
```docker
docker exec -it <コンテナID> /bin/bash  
```
CERN ROOT (C++) グラフ作成 (2)  yをxの計算式として与え、x-yグラフを描画 (class TF1 )

# 概要
xの値の範囲を決め、そのxに対する計算式または関数を指定してx-yグラフを描画する。
これにはCERN ROOTのclass TF1を使う。

# 実行環境

```zsh
sw_vers
ProductName:		macOS
ProductVersion:		14.6.1
BuildVersion:		23G93

root --version
ROOT Version: 6.32.06
Built for macosxarm64 on Sep 21 2024, 18:21:53
From tags/6-32-06@6-32-06
```

# 計算式を文字列で与える
```C++
root [0] auto tf = new TF1("sin","TMath::Sin(x)", 0,10);
root [1] tf->Draw();
Info in <TCanvas::MakeDefCanvas>:  created default TCanvas with name c1
root [2]
```

 ![2024-10-30 18.45.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258007/b6d57e2f-5106-a36b-cbcd-0b29c27341a2.png)

`"TMath::Sin(x)"`が計算式です。２次関数なら`"x*x+3*x+1"`となどとできます。ROOTで使える関数ならいろいろな関数を含めた計算式が指定できます。
第３、4の引数が`x`の値の範囲です。
また、計算した(x,y)の点をマーカーで表示したい場合は次のようにします。

```c++
root [0] auto tf = new TF1("sin","TMath::Sin(x)", 0,10);
root [1] tf->SetMarkerStyle(20);
root [2] tf->Draw("pl");
Info in <TCanvas::MakeDefCanvas>:  created default TCanvas with name c1
root [3]
```
![2024-10-30 18.56.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258007/e4d9352a-964f-54d3-a2e8-0c534f946090.png)
計算しているx座標の数を指定することが次のようにするとできます。
```c++
root [3] tf->SetNpx(30);
```
`Draw`を実行しなくても即座にグラフへ反映されます。マーカーを数えたら30有りました。

![2024-10-30 19.04.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258007/da3d7727-43a8-4362-800f-ae623f1fb0b1.png)

#### パラメータ付き計算式
２次関数$ax^2+bx+c$の$a,b,c$をパラメータとする。

```c++
root [0] auto tf = new TF1("xx","[0]*x*x+[1]*x+[2]", -10,10);
root [1] tf->SetParameters(1,-2,-10);
root [2] tf->Draw();
Info in <TCanvas::MakeDefCanvas>:  created default TCanvas with name c1
root [3]
```
`[0],[1],[2]`がそれぞれ$a,b,c$を表している。`SetParameters`の引数が順番に
`[0],[1],[2]`へ値を設定している。`Draw`の後に`SetParameters`で値を変更すると即座にグラフが更新される。また、個別にパラメータを変更したい場合は`tr->SetParameter(0,3);`とすると`[0]`の値が3に変更されグラフも更新される。

![2024-10-30 19.56.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258007/a2de774d-a034-d803-0c92-0367f53bf4f5.png)

# 計算式をCの関数として定義
上記と同様の２次関数をCの関数で計算する例を示します。
```c++
root [0] Double_t func(Double_t *x, Double_t *p){Double_t xx = *x; return p[0]*xx*xx+p[1]*xx+p[2];}
root [1] auto tf = new TF1("xx",func, -10,10, 3);
root [2] tf->SetParameters(1,-2,-10);
root [3] tf->Draw();
Info in <TCanvas::MakeDefCanvas>:  created default TCanvas with name c1
root [4]
```
計算する関数を`Double_t 関数名(Double_t *x, Double_t *p)`として定義します。`TF1`の第５引数の値の数だけのパラメータを`SetParamters`などで設定した値が　`p`に渡されます。パラメータが無いときは第5引数に０指定するか省略します。

![2024-10-30 20.39.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258007/9c5e62b9-37c3-1ed2-87cb-bc38b5f31493.png)


# 終わりに
使用は限定されますが、`TGraph`より簡便に使えます。また、計算式の設定の仕方は上記以外にも幾つかあります。
【Python】Sleep処理の活用とブロッキングの落とし穴

## はじめに
業務で`time.sleep()`を使った待機処理を学ぶ中で、非同期処理への興味から個人的に`asyncio.sleep()`についても学びました。

`time.sleep()`は同期的にプログラムを停止する一方で、`asyncio.sleep()`は非同期プログラムに適しており、待機中も他の処理が並行して進行します。

この記事では、非同期処理における`asyncio.sleep()`の使い方と、同期的な`time.sleep()`が引き起こす問題を備忘録として整理します。

## 1. `time.sleep()`と`asyncio.sleep()`の違い

### 1-1. `time.sleep()`の基本
- `time.sleep()`はプログラム全体の実行を停止し、指定した秒数だけ待機します。
- シンプルな待機処理では便利ですが、非同期プログラムには不向きです。

```python
import time

print("処理開始")
time.sleep(2)  # 2秒待機
print("2秒後に処理再開")

```
実行結果：
```
処理開始
2秒後に処理再開
```
#### 解説：

1.`print("処理開始")`
- プログラムが開始され、「処理開始」が表示される。

2.`time.sleep(2)`
- 2秒間プログラム全体が停止する。この間、他の操作は行われない。

3.`print("2秒後に処理再開")`
- 2秒が経過した後、次の行が実行され、「2秒後に処理再開」が表示される。


### 1-2. `asyncio.sleep()`の基本
- 非同期処理では、複数のタスクを同時並行で実行できます。
- Pythonでは、非同期の待機に`asyncio.sleep()`を使います。
これにより、1つのタスクが待機中でも、他のタスクが進行できます。

(※)asyncio：
　Pythonで非同期処理を扱うための標準ライブラリ。
　イベントループを使って、複数のタスクを同時並行で処理することができる。

## 2. `asyncio.sleep()`の例

- 以下は、`asyncio.sleep()`を使った非同期プログラムの例です。
- 複数のタスクを並行して実行し、それぞれの待機時間後に結果を出力します。

```python
import asyncio

async def task(name, delay):
    print(f"{name} 開始")
    await asyncio.sleep(delay)  # 非同期で待機
    print(f"{name} 完了: {delay}秒後")

async def main():
    await asyncio.gather(
        task("タスク1", 2),
        task("タスク2", 3),
    )

asyncio.run(main())

```
実行結果：
```
タスク1 開始
タスク2 開始
タスク1 完了: 2秒後
タスク2 完了: 3秒後
```

#### 解説： 実行順序のポイント

1. `main()`が開始され、`asyncio.gather()`でタスク1とタスク2が同時に実行される。
    - タスク1は2秒待機、タスク2は3秒待機する。
2. タスク1とタスク2は同時に「開始」メッセージを出力する。
3. 2秒後、タスク1が完了し、完了メッセージが表示される。
4. さらに1秒後、タスク2が完了し、全てのタスクが終了する。



## 3. ブロッキングの問題：`time.sleep()`の危険性
- 次に、非同期プログラム内で誤って`time.sleep()`を使った場合、全体の処理がどのようにブロックされるかを確認します。

```python
import asyncio
import time

async def blocked_task():
    print("NG例: time.sleep()を使うと…")
    time.sleep(2)  # 他の処理が2秒間ブロックされる
    print("この間に他の処理が実行されない")

async def normal_task(name):
    for i in range(5):
        print(f"{name} 実行中: {i+1}/5")
        await asyncio.sleep(1)  # 非同期で1秒ごとに実行

async def main():
    await asyncio.gather(
        blocked_task(),  # ブロックされるタスク
        normal_task("タスクA"),  # 並行で実行されるべきタスク
    )

asyncio.run(main())

```
実行結果：
```
NG例: time.sleep()を使うと…
この間に他の処理が実行されない
タスクA 実行中: 1/5
タスクA 実行中: 2/5
タスクA 実行中: 3/5
タスクA 実行中: 4/5
タスクA 実行中: 5/5
```

#### 解説： なぜブロッキングが起こるのか？
- `time.sleep()`は同期的な待機を行うため、非同期環境でも全体の進行を止めてしまいます。
- この例では、time.sleep(2)の間、他の非同期タスク（normal_task）が進まなくなり、全体がブロックされてしまいます。

## 4. 解決策：非同期処理では`asyncio.sleep()`を使おう
- ブロッキングを避けるために、非同期プログラムでは `asyncio.sleep()` を使います。
- 修正したコードは以下の通りです。

```python
import asyncio

async def blocked_task():
    print("非ブロッキングの例")
    await asyncio.sleep(2)  # 非同期待機
    print("他の処理も並行して実行される")

async def normal_task(name):
    for i in range(5):
        print(f"{name} 実行中: {i+1}/5")
        await asyncio.sleep(1)  # 非同期で1秒ごとに実行

async def main():
    await asyncio.gather(
        blocked_task(),  # 非ブロッキングのタスク
        normal_task("タスクA"),  # 並行で実行されるタスク
    )

asyncio.run(main())
```
実行結果：
```
非ブロッキングの例
タスクA 実行中: 1/5
タスクA 実行中: 2/5
他の処理も並行して実行される
タスクA 実行中: 3/5
タスクA 実行中: 4/5
タスクA 実行中: 5/5
```

## 5. まとめ
- time.sleep()は同期処理で使い、非同期処理では使わない。
- 非同期環境ではasyncio.sleep()を使うことで、他のタスクがブロックされない。
衆院選で比例に「民主党」と書いた人の数を調べる

### 追記(11/3)

たくさんの反響をいただいてびっくりしています。ありがとうございます。
コメント欄にて効率的な探索法や、多数の自治体のデータなどをご紹介いただいたので、そちらもぜひご一読ください。~~あとスパムっぽいコメントを通報していただけると助かります~~

## トリビアの種

衆議院選挙の比例代表制で「民主党」と書くと、立憲民主党と国民民主党に票が按分されます。

https://seijiyama.jp/article/news/nws20190721-3.html

この記事によれば、立憲と国民、それぞれの投票の割合を求めて、「民主党」と書いた人の数を掛け、小数点第四位を切り捨てたものを加算するとのことです。

ということは、得票比が保たれます。なら、得票数から「民主党」と書いた人の数が計算できるのではないでしょうか？

このトリビアの種、つまりこういうことになります。

> 弊自治体で立憲または国民に投票した1,811人のうち、「民主党」と書いたのは～～～っ、ﾝﾝ！人！

## 実際にやってみた

弊自治体の比例代表の投票結果は以下でした。

* 立憲民主党 1494.538票
* 国民民主党 316.461票

足すと1810.999となるので、票数は全部で1811票で良さそうです。

Qiitaでわざわざ政治の話をしてることからも分かる通り、探索にはプログラムを利用しました。票数はかならず整数になることを利用すれば、もっと効率の良い探索方法があると思いますが、数が小さかったので、男は黙って全探索です。ムダが多いよ～。


```cs
double rikken_actual = 1494.538;
double kokumin_actual = 316.461;

double total = Math.Round(rikken_actual + kokumin_actual);

double rikken_per = rikken_actual / total;
double kokumin_per = kokumin_actual / total;

for(double kakutei = 1; kakutei <total; kakutei++)
{
    double rikken = Math.Round(kakutei * rikken_per);
    double kokumin = Math.Round(kakutei * kokumin_per);

    double anbun = total - rikken - kokumin;

    double rikken_total = rikken + (double)rikken / kakutei * anbun;
    double kokumin_total = kokumin + (double)kokumin / kakutei * anbun;

    if(Math.Floor(rikken_total* 1000) / 1000 == rikken_actual){
        Console.WriteLine($"立憲:{rikken} 国民:{kokumin} 按分:{anbun} -> 立憲{rikken_total:0.0000} 国民{kokumin_total:0.0000}");
    }
}
```

結果は以下の1行でした。数字によっては複数の候補が発生しうりますが、今回はこの内訳でしかこの結果にはなり得ないということです。
```
立憲:1209 国民:256 按分:346 -> 立憲1494.5386 国民316.4614
```

346/1811ですから、弊自治体では、立憲か国民に投票したかった人の、実に2割近くが「民主党」と書いていることになります。結構多いんですねえ。


## いかがでしたか

> 弊自治体で立憲または国民に投票した1,811人のうち、「民主党」と書いたのは **346人**(19.1%)

八分咲きといったところでしょうか。
パフォーマンスモニターのProcessor のCPU使用率が100%超える現象について

パフォーマンスモニターのCPUのログを確認していてProcessorでみるとCPU使用率が100%を超えていることがあるが、端的に言うとProcessorの指標の取り方だとマルチコアのクロックアップに対応していないため起こっている。
クロスアカウントでSQSキューにSNSトピックをサブスクリプションしたらハマった話

# はじめに
とある案件で、**アカウントA**で発報したアラートのメッセージを**アカウントB**のSQSキューに入れる必要がありました。  
なぜかキューにサブスクリプション承認メッセージが飛ばず、ハマりかけたので、皆さんも同じことが無いように共有します。

## SQSキューにSNSのメッセージを受けるためのポリシー

SQSキューでSNSのメッセージを受けるには、以下のようなSQSポリシーを許可している必要があります。

```json
{
  "Version": "2008-10-17",
  "Statement": [
    {
      "Sid": "from-sns",
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      },
      "Action": "sqs:SendMessage",
      "Resource": "arn:aws:sqs:ap-northeast-1:123456789012:SystemName-Env-sqs",
      "Condition": {
        "ArnLike": {
          "aws:SourceArn": "arn:aws:sns:ap-northeast-1:123456789012:SystemName-Env-sqs"
        }
      }
    }
  ]
}
```
## サイ〇リヤ間違え探し難易度MAX
この案件では、SQSポリシーを開発ベンダーで操作できないため、お客様の担当部署に作業依頼を行いました。
その結果、担当者からアタッチされたポリシーがこちらです。
```json
{
  "Version": "2008-10-17",
  "Statement": [
    {
      "Sid": "from-sns",
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      },
      "Action": "sps:SendMessage",
      "Resource": "arn:aws:sqs:ap-northeast-1:123456789012:SystemName-Env-sqs",
      "Condition": {
        "ArnLike": {
          "aws:SourceArn": "arn:aws:sns:ap-northeast-1:123456789012:SystemName-Env-sqs"
        }
      }
    }
  ]
}
```

## 何が違うのか？
はい、何が変わったかわかりますか？
正直、私も作業者も最初は気づかず、30分間まじまじと眺めていましたが、原因がわかりませんでした。

## 正解
正解はここです。
以下の部分が誤っていました。

- 正しい記述: "Action": "sqs:SendMessage"
- 誤った記述: "Action": "sps:SendMessage"

## 教訓
皆さんは手打ちで記入せず、コピペを活用するか、大文字を記入しましょう。
量子コンピュータ入門体験

### 量子コンピュータ

### 得意な計算
経路探索/物流/自動搬送/機械学習/AI/シミュレータ

### 量子コンピュータとは、
普通のコンピュータ＋量子の性質＝量子コンピュータ

### 量子とは
電子/中性子/原子/光子

### 量子の性質
粒子＋波

### 計算方法
量子操作ゲートアルゴリズムを使って計算する

### 使用言語
Python

### GUIを使った計算
ゲート方式で１＋１を計算してみた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576081/03a4f67d-dd17-fab8-a107-b45c3939484f.png)


ゲート方式シミュレータ
https://qniapp.net/%7B%22cols%22%3A%5B%5D%7D



https://qiita.com/meltyyyyy/items/096efb08fb4ec532c330

### 量子コンピュータの課題
ノイズに弱い
四則演算は従来のコンピュータが得意
#paiza #プログラミング #Javascript # 本番環境自動判別方法

**本内容を利用した場合の一切の責任を私は負いません。**

# 概要
この前書いた下記のatcoder版のpaiza版。
(Windows 10+node.js+Visual Studio Codeの場合。)
https://qiita.com/qiita21409102/items/c6fdfafdf76a8f71483a

# 本番環境自動判別方法
Visual Studio Code上でデバッグすると専用の環境変数が設定されるので、それで判別する。

```Javascript
var isSubmit = true;

if (process.env["VSCODE_PID"] != undefined) {
    isSubmit = false;
}
```
Dayjs で割と簡単に「たった今」「23秒前」のような相対表記を実現するワークアラウンド

# バージョン

`dayjs@1.11.11` で動作確認しています。

# 相対表記の実装の基本

```typescript
import dayjs from "dayjs";
import "dayjs/locale/ja";
import relativeTime from "dayjs/plugin/relativeTime";

dayjs.locale("ja");
dayjs.extend(relativeTime);
```

まず標準の相対表記を実装するのはこれ↑だけです。

```typescript
const now = new Date().getTime();
const secondsAgo = now - 1 * 1000;
const minutesAgo = now - 2 * 60 * 1000;
const hoursAgo = now - 2 * 60 * 60 * 1000;

console.log(dayjs(secondsAgo).fromNow());
console.log(dayjs(minutesAgo).fromNow());
console.log(dayjs(hoursAgo).fromNow());

// 数秒前
// 2分前
// 2時間前
```

# 「数秒前」じゃなくて、「たった今」とかにしたい

https://day.js.org/docs/en/customization/relative-time

```typescript
import dayjs from "dayjs";
import "dayjs/locale/ja";
import relativeTime from "dayjs/plugin/relativeTime";
import updateLocale from "dayjs/plugin/updateLocale";

dayjs.locale("ja");
dayjs.extend(relativeTime);
dayjs.extend(updateLocale);
dayjs.updateLocale("ja", {
  relativeTime: {
    future: "%s後",
    past: (value: string) => (value === "たった今" ? value : `${value}前`),
    s: "たった今",
    m: "1分",
    mm: "%d分",
    h: "1時間",
    hh: "%d時間",
    d: "1日",
    dd: "%d日",
    M: "1ヶ月",
    MM: "%dヶ月",
    y: "1年",
    yy: "%d年",
  },
});
```

Locale をこのように指定する必要がありますが、`past` の部分だけちょいと嫌な書き方になっています。
`fromNow()` で「〜〜前」をやろうとするとこの `past` のテンプレートを必ず通るわけですが、`s`に「たった今」が入っていると「たった今前」となってしまうんですね。
仕方ないので上のようにハードコーディングで判定する処理を入れます。

ちなみに relativeTime の変えたいところだけの指定はできず、全部指定しないとエラーになります。

# 「23秒前」のように1分未満もカウントしたい

リアルタイム性の高いアプリケーションではそうしたいこともあるでしょう。
しかし、relativeTime は `ss` をサポートしていないので、他と同じように `ss: "%d秒"` という指定ができません。

https://github.com/iamkun/dayjs/issues/830

```typescript
import dayjs from "dayjs";
import "dayjs/locale/ja";
import relativeTime from "dayjs/plugin/relativeTime";
import updateLocale from "dayjs/plugin/updateLocale";

dayjs.locale("ja");
dayjs.extend(relativeTime);
dayjs.extend(updateLocale);
dayjs.updateLocale("ja", {
  relativeTime: {
    future: "%s後",

    past: (value: string) => (value === "0秒" ? "たった今" : `${value}前`),
    // もしくはたった今の範囲を指定したい場合は
    past: (value: string) => {
      if (value.endsWith("秒")) {
        const seconds = Number(value.split("秒")[0]);
        // この場合、5秒未満なら「たった今」と表示され、5秒以上なら「23秒前」のように表示される
        return seconds < 5 ? "たった今" : `${seconds}秒前`;
      }
      return `${value}前`;
    },

    s: "%d秒",
    m: "1分",
    mm: "%d分",
    h: "1時間",
    hh: "%d時間",
    d: "1日",
    dd: "%d日",
    M: "1ヶ月",
    MM: "%dヶ月",
    y: "1年",
    yy: "%d年",
  },
});
```

`ss` はサポートされていないですが、`s` をテンプレートとした変数展開時には、他と同じようにその秒数が渡されているので、それを使います。

コード内 5 はもちろん自由に設定できます。

あまり嬉しいコードではないですが、とりあえずサクッと実現するならこれが一番簡単そう。
化野の備「暴」録


![備「暴」録バナー.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3917696/2d234191-45bd-9da7-8a62-d276e35f6e89.jpeg)

# 第0回　「自己紹介、今後の予定」


どうも、ただいまオンラインスクールにてLaravelの勉強中でございます。

**「あだしの」**

と申します。

上部中央のバナーはillustratorのテンプレートを参考に私が作成いたしました（原型はほぼないです）。

なぜ、「忘」が「暴」いなっているかというとフォントに忘という字がなかったからです。ただ、備忘録は「忘れないための記録」をあらわします。私の場合は、一度調べた記憶はあるのに、内容をよく覚えていないとイライラして暴れるので備「暴」録でも間違っていないと思います:grinning:

### 私の簡単な自己紹介と開発環境について

PN　：　あだしの（化野）　ぼぶこ　　（下の名前をききょうと名乗るときもあります、きまぐれ）
GEN　：　♀　　　　BIRTH　：　12/6　　　　　　BLOOD　：　O


PCのスペック
OS：Windows
プロセッサ：Intel(R) Xeon(R) CPU E3-1230 v5 @ 3.40GHz   3.40 GHz
実装 RAM：32.0 GB
グラボ：NVIDIA QUADRO P2000


PC仮想化済
（これをやらないと私のPCはUbuntuが動きませんでした。デメリットもありますので実行の際はお気を付けください。また、PC上でもういくつかのOSを動かす処理なのでスペックも要求されます。RAM　16GBは想定しておく必要があります。）

### 最後に
経験者様はご存じであると思いますがWindowsはMac製のものに比べプログラミング最中
エラーの起きる頻度が高いです！！！:triumph:
勉強中にたくさんでてくるので、いつもエラーの対応に追われています。

そのエラーの対応でWindowsユーザーの私がどうしているかや、プログラミングを学ぶ上でこういった勉強法、こう理解するとわかりやすい！といったものを配信していこうと思います。あくまで私の主観なのでそこをご了承いただければと思います。
Next.js の本番環境でのみ mysql2 関連のエラーが出る際の対処

# Github に Issue が立っていました
「Next.js + Drizzle ORM (mysql2, PoolConnection) のバージョンに注意したい話」というタイトルで以前記事を書いたのですが、

済みません、ちょっとソースコードを変えたら同じエラーが出たため違う原因を探していたところ、Githubに既にIssueが立っておりました。失礼いたしました。

https://github.com/sidorares/node-mysql2/issues/1885

# 対処方法

```js:next.config.mjs
/** @type {import("next").NextConfig} */
const config = {
  // これを追加すると良いそうです
  serverComponentsExternalPackages: ["mysql2"],
}
export default config
```

Next.js がバンドル操作を行う際に、Node.js特有の機能を使用するパッケージを上手く取り入れられない場合があるそうです。
https://nextjs.org/docs/app/api-reference/next-config-js/serverExternalPackages
Next.jsは[そういった性質を持つライブラリのリスト](https://github.com/vercel/next.js/blob/canary/packages/next/src/lib/server-external-packages.json)を使ってある程度自動で対処しているらしいのですが、
node-mysql2 パッケージはその対象外になっているので、自分で設定する必要があるというのが問題の本当の原因だった可能性が高いです。

# もう少し推察
何かしらOSに関わる機能（ファイルシステムに触る、他の実行ファイルやコマンドを呼び出す 等）の動作をするものはこの条件に該当しそうですから、
そういったものをNext.jsと一緒に使う際には、事前に `serverComponentsExternalPackages` に入れておく等しようと思います。
Macのウィンドウサイズが中途半端になる場合の解決方法

MacBookAir（macOS Sequoia 15.0.1）を使用する際のウィンドウサイズの調整にBetterSnapToolというアプリケーションを使用している．
先日普段通り使用していると，ウィンドウを端に持って行った際にウィンドウサイズが隙間が空いて中途半端になる事態が発生．

以下は治し方
Macの「設定」→「デスクトップとDock」→「タイル表示されたウィンドウを隙間を入れて配置」をオフ
multiple dev containerですぐに立ち上げられるモノレポなローカル開発環境を作るぞ！

# はじめに
勉強するときに可搬性のある開発環境が欲しい！
いわゆるモノレポ環境をdevcontainerでやってみたい！

ということで、今回はdevcontainerとdocker-compose.yamlを使って**multiple dev container**な環境を作っていこうと思います！

# できたもの
コマンドパレットから`Dev Containers: Open Folder in Container`コマンドを実行すると2種類のdevcontainerが選べます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2978104/1bcd48f6-e719-5cdf-f353-5e97e9b610bc.png)

devcontainerの中ではそれぞれ`frontend/`配下と`backend/`配下のファイルしか見えないようになっています。設定次第ではルートディレクトリ配下を見ることもできます！

これはbackendのdevcontainerを開いたときのフォルダ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2978104/a567ae3e-7a53-c610-fc70-dc4138f16e92.png)

# 作成方法
プロジェクトの`.devcontainer/`の下にディレクトリを作成して、各ディレクトリの中で`devcontainer.json`を作るだけ！
簡単ですねーーー

devcontainer.jsonの中でdocker-compose.ymlの中のコンテナを指定しているので、どちらか片方のdevcontainerを立ち上げるとフロント・バック・DBが同じネットワークで立ち上がるようになっています。

ルートのdocker-compose.ymlの中で.devcontainer配下のDockerfileを読み込んでいます。理由として、devcontainerを使うときはdevcontainer用のイメージを使わないといけないので、将来的にプロダクトをデプロイする時用のコンテナイメージと分けたいなーなんて妄想をしたためです。（意味あるかな？）

### `./devcontainer/backend/devcontainer.json`
```
{
  "name": "Backend Container",
  "dockerComposeFile": ["../../docker-compose.yml"],
  "service": "backend",
  "workspaceFolder": "/workspace/backend"
}
```
### `docker-compose.yml`
```
services:
  db:
    image: postgres:14
    container_name: db
    environment:
      POSTGRES_USER: local_user
      POSTGRES_PASSWORD: local_password
      POSTGRES_DB: local_db
    networks:
      - app-network

  backend:
    build:
      context: .devcontainer
      dockerfile: backend/Dockerfile
    volumes:
      - .:/workspace:cached
    command: sleep infinity
    environment:
      DATABASE_URL: postgres://local_user:local_password@db:5432/local_db
    depends_on:
      - db
    networks:
      - app-network
    ports:
      - "8000:8000"

  frontend:
    build:
      context: .devcontainer
      dockerfile: frontend/Dockerfile
    volumes:
      - .:/workspace:cached
    command: sleep infinity
    depends_on:
      - backend
    networks:
      - app-network
    ports:
      - "3000:3000"

networks:
  app-network:
    driver: bridge
```

## ディレクトリ構造
```
/
├── .devcontainer
│   ├── backend
│   │   ├── Dockerfile
│   │   └── devcontainer.json
│   └── frontend
│       ├── Dockerfile
│       └── devcontainer.json
├── .git/
├── .gitignore
├── README.md
├── backend
│   └── hello.py
├── docker-compose.yml
└── frontend
    └── hello.js
```



# リポジトリ
githubに設定まとめてみたのでよかったら見てみてください！
- フロントエンドコンテナ：TypeScript
- バックエンドコンテナ：Python

https://github.com/re2osushi8888/multiple-devcontainers

こだわりポイントとして、各devcontainerでgitを使えるようになっています！gitの設定はリポジトリしているのでのREADME.mdに記載しているので見てみてください！
[試行錯誤した時の記事](https://qiita.com/re_2osushi8888/items/508b646d61daefeb7d70)

## まとめ
devcontainerを開発用途によって使い分けるとフォルダのスコープが狭まって個人的には結構使い勝手がいいです！
特に、コマンドパレットで`Dev Containers: Switch Container`を使ってフロントコンテナとバックエンドコンテナを行き来するのが楽しい...！
multiple dev containerぜひ試してみてください！

## 参考記事
https://qiita.com/nimowagukari/items/7e2660621890e2b015b3  

https://code.visualstudio.com/remote/advancedcontainers/connect-multiple-containers
フレームワークとライブラリの本当の違い

## はじめに
「フレームワークってライブラリの上位互換なの？」
「結局どっちを使えばいいの？」

私も最初はこんな疑問を持っていました。今回は現場での経験を交えながら、両者の違いをしっかり解説していきます。

## フレームワークの本質
フレームワークは「型にはめる」ための枠組みです。これは一見すると制約のように感じるかもしれません。しかし、この「型」にはとても重要な意味があります。

実はフレームワークは、電車とレールの関係に似ています：

→ **レール（フレームワーク）** が敷かれている
→ **電車（あなたのアプリ）** はそのレール上を走る
→ 行き先（ゴール）は決まっているけど、途中の駅（機能）は自分で選べる
→ 脱線の心配がない（セキュリティやパフォーマンスが保証されている）

### ハリウッドの原則
フレームワークの特徴を表す有名な言葉があります：
> "Don't call us, we'll call you"（ハリウッドの原則）

これはハリウッドのオーディションから来ている言葉ですが、フレームワークの本質を的確に表現しています。

具体的には：
→ フレームワーク側があなたのコードを呼び出す
→ あなたはフレームワークに呼ばれるのを待つ

実際のコードで見てみましょう：

```javascript
// Railsの例
class UsersController < ApplicationController
  def index  # フレームワークがこのメソッドを呼び出す
    @users = User.all
  end
end

// Next.jsの例
export default function Page() {  // フレームワークがこの関数を呼び出す
  return <h1>Hello, World!</h1>
}
```

### なぜ型にはめるのか
電車の例で考えてみましょう：

1. **安全性**
   → レールがあるので脱線しない
   → 既定のルートが保証されている

2. **効率性**
   → 既に敷かれたレールの上を走るので、道を作る必要がない
   → 開発の土台が用意されている

3. **予測可能性**
   → 誰が運転しても、同じ駅に着ける
   → 共通の設計思想に基づいた開発が可能

### 具体例：Next.jsでの開発
Next.jsを使う時、これはまるで「駅」のような決まった場所があります：
```
pages/
  ├── _app.js      /* 始発駅：アプリ全体の設定 */
  ├── _document.js  /* 運行ダイヤ：HTMLドキュメントの設定 */
  └── index.js      /* 終着駅：トップページの実装 */
```

### フレームワークの特徴
1. **統一された設計思想**
   → コードの一貫性が保たれる
   → メンテナンス性が向上する

2. **既定の実装パターン**
   → セキュリティ対策が組み込み済み
   → パフォーマンスの最適化が標準装備

3. **明確な制約**
   → 決められたパターンでの実装
   → 予測可能な動作

## ライブラリとは
ライブラリは工具箱のようなものです。
必要な道具を、必要な時に、必要なだけ使えます。

### ライブラリの特徴
1. **高い自由度**
   → 必要な機能のみを選択可能
   → 独自の実装パターンを構築できる
   → ただし、自由すぎて「オレオレ実装」になりがち

2. **保守性の課題**
   → ディレクトリ構造が開発者次第
   → コーディング規約が統一されにくい
   → チーム開発では保守性が低下する危険性

3. **柔軟な組み合わせ**
   → 他のライブラリとの統合が容易
   → カスタマイズ性が高い
   → 反面、依存関係が複雑化する可能性

### 保守性の違いを理解する
#### フレームワークの場合
```javascript
// Next.jsの例
// pages/users/[id].js
export default function UserPage({ user }) {
  return <div>{user.name}</div>
}
```
→ ファイルの場所で役割が明確
→ どのチームメンバーが書いても同じ構造
→ 新メンバーが参加しても理解しやすい

#### ライブラリの場合
```javascript
// Reactの例（チームごとに構造が異なる可能性）
// Team A
/src/components/Users/UserDetail.jsx

// Team B
/src/pages/users/detail/index.jsx

// Team C
/src/features/user/components/Detail.tsx
```
→ チームごとに異なる構造になりがち
→ レビュー時に基準が曖昧
→ 長期的な保守性に課題

### 現場での課題
フレームワーク：
→ ルールに従えば自然と保守性が高まる
→ チーム全体で同じ方向性を維持できる
→ フレームワークのアップデートに追従する必要がある

ライブラリ：
→ 自由度が高い分、オレオレな開発手法になりやすい
→ ディレクトリの構造がバラバラに
→ ファイルの構成や命名規則が人によって異なる
→ コードレビューで指摘が多くなる傾向

そのため、ライブラリを採用する際は以下が必須になります：
→ コーディング規約の策定
→ ディレクトリ構造の取り決め
→ コンポーネントの粒度の統一
→ 命名規則の確立

## 実務での選択基準
プロジェクトの特性に応じて、適切な選択をする必要があります。

### フレームワークが適している場合
→ 大規模なチーム開発
→ 納期が厳しいプロジェクト
→ 新人開発者が多いチーム
→ 長期的なメンテナンスが必要

### ライブラリが適している場合
→ 小規模な開発
→ カスタマイズ性が重要
→ 経験豊富な開発者が多い
→ パフォーマンスの最適化が必須

## まとめ
フレームワークは「電車とレール」：
→ レールの上を安全に走れる
→ 決められた線路上での自由
→ 誰が運転しても目的地にたどり着ける
→ 保守性が自然と高くなる

ライブラリは「工具箱」：
→ 必要な道具を選んで使用
→ 使い方は開発者次第
→ 組み合わせ方で無限の可能性
→ ただし、規約を決めないと保守性が低下

結局のところ：
→ フレームワーク = 安全性と保守性の重視
→ ライブラリ = 自由度と柔軟性の重視

プロジェクトの要件とチームの特性を考慮して、適切な選択をすることが重要です。

#programming #フレームワーク #ライブラリ #frontend
【Vket Cloud】動画つき！ゼロから始めるHeliScript超入門⑬ - HeliScriptをより使いこなすには

# はじめに
Vket Cloudでは、「HeliScript」という独自のスクリプトを使用してコーディングを行うことで、ワールド内に高度なギミックを導入することが出来ます。

本記事ではHeliScriptをより使いこなすための方法について紹介します。

# 1. 公式マニュアルを読む

本連載記事にて何度か紹介した、[公式マニュアル](<https://vrhikky.github.io/VketCloudSDK_Documents/latest/hs/hs_overview.html>)には、HeliScriptのリファレンスが記載してあります。

本連載記事では解説していない機能の記載も多数あるので、ぜひご覧ください。

# 2. アセットストアのアクティビティクラスを確認する
[Vket Cloudアセットストア](<https://cloud.vket.com/account/asset/store>)にて、提供者を公式、オブジェクトをアクティビティに設定することで、公式が提供する**アクティビティクラス**のみを表示することが出来ます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3788807/0b296514-b2bf-c9e0-b944-22cdb50344ea.png)

::: note
アクティビティクラスとは？
VKC Item Activityコンポーネントを使って実装する、プリセットのギミックを簡単に設置することが出来る機能です。
:::

アクティビティクラスの中にもHeliScriptが使用されており、アクティビティクラス内で実現している機能がHeliScriptでどのように実装されているか、参考にすることが可能です。
ただし、`hsItemGetOwnScene()`など、アクティビティクラスの中限定でしか使用できない関数を使用している箇所もあるため、全く同じHeliScriptが通常のワールドで使用できるとは限りません。

# 3. Vket Cloudに関する記事を確認する

HeliScriptについて学習できる連載記事に、[HeliScriptでリッチなアスレチックワールドを作ろう！【コピペで使えるサンプルコード付き】](<https://qiita.com/IwahanaFuku/items/63e6bbca2bc1f13ed57e>)があります。

アスレチックワールドの作成を通してHeliScriptについて学習ができる連載記事なので、学習には最適です。

# 4. Vket Cloud公式Discordチャンネルに参加する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3788807/f9fc10a2-5c6f-12ad-4544-ab0c2d834c72.png)
[Vket Cloud公式Discordチャンネル](<https://discord.gg/MQYj2XWCz8>)では、質問フォーラムがあるほか、ワールドづくり教室やVket Cloud勉強会といったイベントが開催されております。
※上記リンクよりDiscordチャンネルに参加することが出来ます。

HeliScriptについてわからないことをフォーラムから質問したり、勉強会に参加して新しい知識を手に入れたりすることが出来ます。
過去の勉強会の映像も確認することが可能です。

付録 : [用語集](<https://qiita.com/shirapy/private/d91f164b83e8eab06410>)
前 : [⑫ HeliScriptにおけるコンポーネントとアイテムの関係性](<https://qiita.com/shirapy/items/ed8bbde518d4e4606c9b>)
【Vket Cloud】動画つき！ゼロから始めるHeliScript超入門⑫ - HeliScriptにおけるコンポーネントとアイテムの関係性

# はじめに
Vket Cloudでは、「HeliScript」という独自のスクリプトを使用してコーディングを行うことで、ワールド内に高度なギミックを導入することが出来ます。

本記事では、HeliScriptにおけるコンポーネントとアイテムの関係性について紹介します。
やや専門的な話になりますが、理解することでHeliScriptの拡張性をグッと広げることが出来ます。

# 動画

<iframe width="560" height="420" src="https://www.youtube.com/embed/dhtrt-uiYj4?si=fyDl6fD-isT_mKS3" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

# コンポーネントって？

HeliScriptを作成した際、自動で1つ生成される機能の塊です。
コンポーネントの中に関数を登録することが出来ます。
アイテムと紐づけが可能なのはHeliScript1ファイル単位ではなく、コンポーネント単位となります。

また、1つのHeliScriptに複数個のコンポーネントを作成することも可能です。

# アイテムとの紐づけ

⑧ - HeliScriptでシーン上のアイテムを取得するで紹介したとおり、Vket Cloudでは、シーンを構成する要素として「アイテム」という単位が用いられています。
アイテムはコンポーネントを持つことが可能です。
VKC Item Fieldを持つオブジェクトにVKC Attribute Scriptを付与し、HeliScriptを持たせた際、ビルド時に生成されるシーン情報jsonファイルには下記画像のようにcomponentsという項目内に要素が追加されていることが確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3788807/c2b34141-9a1a-a3c5-b577-1f77b6091925.png)


また、1つのアイテムに複数のコンポーネントを持たせることが可能です。

また、ひとつのコンポーネントを複数のアイテムに付けた際、それぞれのコンポーネントが独立して動作します。
「アイテムAが持つコンポーネント」といった状態になります。

# イメージ

アイテムとコンポーネントは演劇の役者と台本のような関係性にあります。
Vket Cloudにおける役者であるアイテムに台本であるコンポーネントを持たせることで、
アイテムは台本に書かれている動きをするし、台本を複数個持たせることでその役者はそれぞれの台本を演じることが出来るようになるし、同じ台本を複数の役者に渡すことでそれぞれの役者が同じ演技をすることが出来るようになります。

# コンポーネント間の値受け渡し

`Item.CallComponentMethod()`を利用することで、他のアイテムが持つコンポーネントの関数を発火することが出来ます。
ただし、対象の関数はpublicである必要があります。
これを利用することで、値渡しを行うことが可能です。

```

component ExampleA{

    private int a;

    public ExampleA(){
        a = 0;
        hsSystemWriteLine("aの初期値は%dです" % a); // コンソールに変数aの初期値を出力
    }

    public void addValue(string s){
        int value;
        value = s.ToInt();
        a += value;
        hsSystemWriteLine("加算後のaは%dです" % a); // 値を加算し結果を出力
    }

}

component ExampleB{
    Item self;

    public ExampleB(){
        self = hsItemGetSelf(); // Itemクラス変数にこのコンポーネントを持つアイテムの情報を格納
        self.CallComponentMethod("ExampleA","addValue","3"); // もう1つのコンポーネントの関数を実行
    }
}

```

上記では、同一アイテム内の2つのコンポーネントにて、片方のコンポーネントが持つ関数をもう片方のコンポーネントから発火し、操作する例になります。
これにより、

```
aの初期値は0です
加算後のaは3です
```
といった出力がされます。

# まとめ
プログラムを動作させるだけであれば、1つのコンポーネントにすべての機能を詰め込むといった実装方法も可能ですが、コンポーネント概念を理解し、コンポーネントごとに機能を分担することで、効率的で分かりやすい実装が可能となります。

このような実装をすることで、「この部分の機能を改修したい」となった際に編集を行うべき場所が分かりやすくなり、保守性が向上します。

また、他コンポーネントの関数を作用させる処理の作り方は、
本記事で紹介した方法以外にも、[クラス定義](<https://vrhikky.github.io/VketCloudSDK_Documents/latest/hs/hs_class.html>)や[HSMessage](<https://vrhikky.github.io/VketCloudSDK_Documents/latest/hs/hs_class_hsmessage.html>)を使う方法もあります。

HeliScriptでの開発に慣れたら、効率の良い開発にもチャレンジしてみましょう。

次 : [⑬ HeliScriptをより使いこなすには](<https://qiita.com/shirapy/private/e886683b34132c508f4f>)
前 : [⑪ HeliScriptでプレイヤーを取得しワープさせる](<https://qiita.com/shirapy/items/f798f8daef57840035fc>)
【Vket Cloud】動画つき！ゼロから始めるHeliScript超入門⑪ - HeliScriptでプレイヤーを取得しワープさせる

# はじめに
Vket Cloudでは、「HeliScript」という独自のスクリプトを使用してコーディングを行うことで、ワールド内に高度なギミックを導入することが出来ます。

本記事ではHeliScriptのPlayerクラスの概要とHeliScriptからプレイヤーを移動させる方法を紹介します。

# 動画
<iframe width="560" height="420" src="https://www.youtube.com/embed/G8YSKWxPnJc?si=3kYKiq2tIwUOHQQ4" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

# Playerクラス
Playerクラスはプレイヤーに対し、移動や名前取得などの制御を加えることが出来る関数が備わっているクラスです。
Item同様、変数宣言を行い`hsPlayerGet()`関数を使用し取得します。

```
    Player player; // Playerクラス変数playerの宣言

    ...(中略)...
    
    player = hsPlayerGet(); // プレイヤーの情報を取得
    player.SetPos(targetVector3); // プレイヤーをtargetVector3で定義した座標へワープ
```

:::note
プレイヤー情報の取得はPlayerクラス関数を使用する直前で行うことで、動作が安定します。
:::

# プレイヤーを移動させる

前節の例でも使用していますが、プレイヤーをワープさせるための関数はItemの移動と同様、`SetPos()`関数を使用します。
また、現在のプレイヤーの座標取得も同様で、`GetPos()`関数を使用することで可能です。

::: note warn
**注意点**
`SetPos()`関数でプレイヤーをワープさせた際、カメラ位置がプレイヤーの背面にワープします。
SetPosの第2引数にfalseを設定することで`SetPos()`発火時、カメラ位置をリセットしない設定が可能です。
詳しくは次節で紹介します。
:::

## 常にゆっくり移動するギミック

Update関数内で`SetPos()`を使用することで、プレイヤーを徐々に移動させることが可能です。
アスレチックワールドを作る時などに便利です。
```
    Player player; // プレイヤークラス変数の定義
    Vector3 player_pos; // プレイヤー座標を格納する変数
    Vector3 move_velocity; // プレイヤー移動量を格納する変数

    public void Update(){ 
        player = hsPlayerGet(); // プレイヤーの情報を取得
        player_pos = player.GetPos(); // プレイヤーの現在座標を取得
        move_velocity = makeVector3(0.0f , 0.0f, 0.025f); // 移動量を設定
        player_pos.Add(move_velocity); // プレイヤー座標に移動量を追加
        player.SetPos(player_pos, false); // 更新後の座標をプレイヤーに反映、カメラリセットしない
    }
```

上記の例では、プレイヤーの座標を取得し、Z方向に少しだけ移動したものに更新することで、プレイヤーが常にゆっくりZ方向に進み続けます。
また、プレイヤーの座標に別途Vector3を追加する方法で実装することで、キー入力によるプレイヤー移動と併用することが出来ます。

上記の例では、`SetPos()`関数使用時に第2引数でfalseを追加していました。
このように、`SetPos()`関数では第2引数のbool値によりワープ実行時にカメラをリセットするかしないかを設定することが可能です。
falseを入力することで、ワープによってカメラ位置が変更されることが無くなり、常にゆっくり進み続ける関数実行中でも自由にカメラを動かすことが可能となります。

次 : [⑫ HeliScriptにおけるコンポーネントとアイテムの関係性](<https://qiita.com/shirapy/private/ed8bbde518d4e4606c9b>)
前 : [⑩ HeliScriptでVector3を使ってシーン上のアイテムを移動させる](<https://qiita.com/shirapy/items/0900d87929511b27943a>)