OmniAICreator/Qiita-1.07M huggingface dataset:
[ Godot 4 ] Godotを始めたばかりの人へ

# はじめに
## ターゲット層
* 記事などを読んだが、プログラムの構造が読み込めななかった人
* pythonなどがある程度わかっている人

## Godot とは
Github で開発されているオープンソースのクロスプラットフォーム用ゲームエンジン

# スクリプト
nodeを配置した後、nodeをUI上で右クリックするとscriptをアタッチすることができる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3794489/8b22f7a7-8ab2-7b0f-0b5d-00536056dcc2.png)
### スクリプトをアタッチするとは？
スクリプトをアタッチするとはそのnodeの動きを制御するコードを書く・繋げる ことである。  


## 最初にスクリプトをアタッチしたときにでてくるコード
スクリプトをアタッチするとこのようなコードが出てくる
```GDscript
extends Node


# Called when the node enters the scene tree for the first
func _ready():
	pass


# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
	pass

```
## コードの解説
### 一行目のコード`extends Node`
```GDscript
extends Node
```
これはスクリプトがアタッチされているnodeの種類を表す。この場合`Node`nodeにアタッチしたためこのようになっている。例えば`button`nodeにアタッチしたら
```GDscript
extends Button
```
となる

### 五行目のコード`func _ready():`
```GDscript
func _ready():
    pass
```
組み込まれている`_ready()`関数を定義している。この関数はプログラム上で呼ばれていることを想定しておらず、ゲーム画面でスクリプトが読み込まれた後の一フレームで **一回だけ** 呼ばれる。

注）
GDscriptでは関数を
```GDscript
func 関数名(引数):
    #中身
```
で定義する。

### 10行目のscript `func _process(delta):`
```GDscript
func _process(delta):
	pass
```
組み込まれている`func _process(delta):`関数を定義している。この関数はプログラム上で呼ばれていることを想定しておらず、一定期間おき（基本的に60fps）に自動で呼ばれ、`delta`に前回呼ばれてからのミリ秒が入る。

# 終わりに
最後まで読んでくださってありがとうございます。
自分がGodotはじめて初めてつまずいたところを中心にまとめました。
これからも更新します。

#### 関連記事
https://qiita.com/098orin/items/31828e617a1cb764a9f8

https://qiita.com/098orin/items/0f3f433ad653a6feba7d
Oracle Diagnostics PackとTuning Packが必要なビューやパッケージ等

# はじめに
Oracle Databaseにはパフォーマンス分析等に使える様々なビューやパッケージ等がありますが、利用するには適切なライセンスが必要です
※下記の記載は19cのマニュアルを参照して記載しています。確認して記載していますが、最終確認はマニュアルをご参照ください。

https://docs.oracle.com/en/database/oracle/oracle-database/19/dblic/Licensing-Information.html#GUID-68A4128C-4F52-4441-8BC0-A66F5B3EEC35

# 前提
オンプレミスが対象です

:::note info
Oracle Cloud (OCI) 上のBase DatabaseのEE以上、ExaCS/CCの場合、下記のライセンスが含まれています
・Oracle Diagnostics Pack
・Oracle Tuning Pack
・Oracle Data Masking and Subsetting Pack
・Oracle Real Application Testing
:::

# Oracle Diagnostics Packが必要なビューやパッケージ等
## パッケージ、関数
* DBMS_ADDM
* DBMS_PERF
* DBMS_UMF
* DBMS_WORKLOAD_REPOSITORY
* DBMS_ADVISOR ※下記条件を満たす場合
  * 「advisor_name」パラメータの値として「ADDM」を指定した場合か、「task_name」パラメータの値にADDMで始まる値を指定した場合にライセンスが必要
* DBMS_WORKLOAD_REPLAY.COMPARE_PERIOD_REPORT関数

## ビュー、テーブル
* V$ACTIVE_SESSION_HISTORYとその基礎となる表X\\$ASH
* DBA_STREAMS_TP_PATH_BOTTLENECK
* DBA_ADDM_で始まるすべてのビュー
* DBA_HIST_で始まるすべてのビューとその基礎となる表
ただし、下記のビューは例外（ライセンス不要）
  * DBA_HIST_SNAPSHOT
  * DBA_HIST_DATABASE_INSTANCE
  * DBA_HIST_SNAP_ERROR
  * DBA_HIST_SEG_STAT
  * DBA_HIST_SEG_STAT_OBJ
  * DBA_HIST_UNDOSTAT
* DBA_ADVISOR_で始まるすべてのビューで、下記条件を満たす場合
  * ビューに対する問合せで、ADVISOR_NAME列内にADDMの値を持つ行、またはTASK_NAME列内にADDM*の値を持つ行、またはそれに対応するTASK_IDの行が戻された場合にライセンスが必要
* DBA_STREAMS_TP_COMPONENT_STAT　※下記条件を満たす場合
  * STATISTIC_UNIT = 'PERCENT'であるもの
* 下記のモニタリングビュー
  * MGMT$ALERT_ANNOTATIONS
  * MGMT$ALERT_CURRENT
  * MGMT$ALERT_HISTORY
  * MGMT$ALERT_NOTIF_LOG
  * MGMT$AVAILABILITY_CURRENT
  * MGMT$AVAILABILITY_HISTORY
  * MGMT$BLACKOUT_HISTORY
  * MGMT$BLACKOUTS
  * MGMT$METRIC_COLLECTIONS
  * MGMT$ALERT_CURRENT
  * MGMT$METRIC_DAILY
  * MGMT$METRIC_DETAILS
  * MGMT$METRIC_HOURLY
  * MGMT$TARGET_METRIC_COLLECTIONS
  * MGMT$TARGET_METRIC_SETTINGS
* 下記のテンプレートビュー
  * MGMT$TEMPLATES
  * MGMT$TEMPLATE_METRIC_COLLECTION
  * MGMT$TEMPLATE_METRIC_SETTINGS
  * MGMT$TEMPLATE_POLICY_SETTINGS

## SQL
* $ORACLE_HOME/rdbms/admin/ディレクトリ以下の下記SQL
  * awrrpt.sql
  * awrrpti.sql
  * awrgrpt.sql
  * awrgrpti.sql
  * awrgdrpt.sql
  * awrgdrpi.sql
  * addmrpt.sql
  * addmrpti.sql
  * ashrpt.sql
  * ashrpti.sql
  * awrddrpt.sql
  * awrddrpi.sql
  * awrsqrpi.sql
  * awrsqrpt.sql
  * awrextr.sql
  * awrload.sql
  * awrinfo.sql
  * spawrio.sql
  * spawrrac.sql

# Oracle Tuning Packが必要なビューやパッケージ等

* DBMS_ADVISOR　※下記条件を満たす場合
    * advisor_nameパラメータの値が「SQL Tuning Advisor」または「SQL Access Advisor」である場合
* DBMS_AUTO_SQLTUNE
* DBMS_PERF
* DBMS_SQL_MONITOR
* DBMS_SQLTUNE 
※下記を除く
    * ADD_SQLSET_REFERENCE
    * CAPTURE_CURSOR_CACHE_SQLSET
    * CREATE_SQLSET
    * CREATE_STGTAB_SQLSET
    * DELETE_SQLSET
    * DROP_SQLSET
    * LOAD_SQLSET
    * PACK_STGTAB_SQLSET
    * REMOVE_SQLSET_REFERENCE
    * SELECT_CURSOR_CACHE
    * SELECT_SQLSET
    * SELECT_WORKLOAD_REPOSITORY
    * UNPACK_STGTAB_SQLSET
    * UPDATE_SQLSET
* V$SQL_MONITOR
* V$SQL_PLAN_MONITOR
* $ORACLE_HOME/rdbms/admin/sqltrpt.sqlのレポート
ガイドターゲティング：複数エレメントがあった場合に最初に見えたエレメントをターゲットする

メモシリーズ：

下記記事の補足
[ガイドターゲティング：複数同じエレメントがあった場合、指定のエレメントをターゲットする方法](https://qiita.com/daichiiiiiii/items/4b305e09e5e8bf55ad3c)


アプリ上同じ要素が複数あり、今画面内に見えてるのもの(見えてる中で①番目要素)に対してターゲットしたい場合の発掘方法


```javascript
//要素郡とってくる
const elements = document.querySelectorAll('#likebtn');

//ブラウザ上表示されているものを探す
for (let i = 0; i < elements.length; i++) {
    const element = elements[i]
    const rect = element.getBoundingClientRect()
    if (
        rect.top >= 0 &&
        rect.left >= 0 &&
        rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
        rect.right <= (window.innerWidth || document.documentElement.clientWidth)
    ) {
        //見えてるものの最初の要素にカスタム属性追加する
        //step 2でターゲットする
        element.setAttribute('firstVisible', 'yes')
        console.log(i)
        //loop抜ける
        break
    }
```
Google Colaboratoryでスプレッドシートを簡単に読み込む方法

# はじめに
私は業務でよくColabを使っています。
思い返してみると、使い始めたばかりの時は、「どうやってスプレッドシートを読み込むんだ？！」と毎回悩んでいました。
そこで、同じ悩みを持つ方を１人でも減ったらいいなと思い、私が安定した方法を記載します。

なおサンプルコード・スプレッドシートを公開していますので、お好みに合わせてご覧ください。

https://drive.google.com/drive/u/0/folders/1JXb6FASk363EjE9JV35YKnl7v5cygPzl

# 場面設定
以下のような状況を仮定しています。

Google Drive上のスプレッドシート「ダイエット記録」をPythonで加工や可視化を行いたい。
そのために、まずスプレッドシートを読み込ませたい。
![スクリーンショット 2024-05-29 19.24.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/846404/cb8859c5-c7b6-5a23-caeb-21839c3fabd2.png)

# 1. データの読み込み
早速コードをご紹介いたします

1. よく使うライブラリをインポート
    ```python
    import pandas as pd
    pd.set_option('display.max_columns', None)
    
    import numpy as np
    import seaborn as sns
    sns.set()
    
    !pip install japanize-matplotlib
    import matplotlib.pyplot as plt
    import japanize_matplotlib
    japanize_matplotlib.japanize()
    ```
1. 認証する
    ```python
    # 認証のためのコード
    from google.colab import auth
    auth.authenticate_user()
    
    import gspread
    from google.auth import default
    creds, _ = default()
    
    gc = gspread.authorize(creds)
    ```
1. スプレッドシートのURLとシート名を指定する
    ```python
    ## スプレッドシートを開く（シートURLから）
    url = "https://docs.google.com/spreadsheets/d/12GsIwLvAX8vGNA1m1XWM_YupRG2oGIJOhQ15KiDeocs/edit#gid=0"
    ss = gc.open_by_url(url)
    
    # シートを特定する（シート名で特定）
    st = ss.worksheet("シート1")
    
    # スプレッドシートのデータをPandasのDataframeに変換する。
    rows = st.get_all_values()
    df = pd.DataFrame.from_records(rows[1:], columns=rows[0])
    ```
1. 結果を確認する
    ```python
    df.head(10)
    ```
# 2. データ型の変更
1. データ型を確認すると、すべてobject型になっています
    ```python
    df.info()
    ```
2. 必要に応じてデータ型を変更します
    ```python
    # floatに変更
    num_cols = ['体重']
    df[num_cols] = df[num_cols].astype(float)
    
    # datetimeに変更
    datetime_cols = ['日付']
    for col in datetime_cols:
        df[col] = pd.to_datetime(df[col], format='%Y/%m/%d', errors='coerce')
    ```
3. きちんと変更されたか、再度確認します
    ```python
    df.info()
    ```

# 3. 可視化
1. 場面設定に基づいて、可視化してみます。
    なお、最初にjapanize_matplotlibをインポートしているので日本語で表示できます。

    ```python
    # 折れ線グラフの作成
    plt.figure(figsize=(10, 5))
    plt.plot(df['日付'], df['体重'], marker='o', linestyle='-', color='b')
    
    # グラフのタイトルとラベルを設定
    plt.title('日付と体重の推移')
    plt.xlabel('日付')
    plt.ylabel('体重 (kg)')
    
    # グラフを表示
    plt.grid(True)
    plt.show()
    ```

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/846404/fa8e8556-0840-cf5f-80ec-52f6d1234b71.png)

# 終わりに
最後までお読みいただきありがとうございました!
RTX1200のNetvolanteDNS(DDNS)の設定の仕方について解説

# まず何でDDNSをすることになったのか
まあ答えは簡単でプロパイダーが動的ip契約だからですね。
「固定IPだと値段高くなるし、hmmせやDDNS使っちゃえ!」
ってのが動機です。

:::note info
DDNSとは:動的(ダイナミック)に、変動するユーザーのグローバルIPアドレスに対して、固定のホスト名(ドメイン)でつないでくれるサービスのことです。
:::
※参照

https://www.iodata.jp/products/plant/2002/npbbrsx/dyndds1.htm
## やり方
まずルーターのwebGUIに接続します(初期設定だと192.168.100.1)
そして管理者向けトップページに行きます。
![スクリーンショット 2024-05-29 190643.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3795539/65b5deb2-3d84-72b3-acaa-ff973937f36c.png)
そしたら左の【運用サポート機能】から【保守】を選択(一番下です)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3795539/bc408b48-5b56-9dae-f948-fb24491b6b2c.png)
そして【設定の管理】から【コマンドの入力】を実行してください。
![s-CB_0002.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3795539/5c1e8136-9f34-9c1d-5520-ee4501838942.jpeg)
そしたらこんなの出てくると思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3795539/2e5f5aa7-efb8-9da5-f182-b0cda658ad52.png)
その四角いところに、下のように書いてDDNSを設定します。

```
pp select 1
netvolante-dns hostname host pp 指定したいホスト名
netvolante-dns go pp 1
save
```
![スクリーンショット 2024-05-29 184832.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3795539/6ea64333-35d1-bac8-ce44-215ccef0208c.png)

:::note warn
ホスト名は「指定したいホスト名.aa0.netvolante.jp」になります。
指定したいホスト名のところだけ書いてください。
:::

:::note warn
指定したいホスト名は半角英数字でお願いします。
:::
さて実行するとこうなると思います
![スクリーンショット 2024-05-29 185026.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3795539/95c24253-04b8-0d50-58c9-f8d2494a7f4a.png)

これで成功です。(失敗した人は別のホスト名で試してみましょう)

:::note info
この画像はF12(検証)で編集したものです。
:::

じゃあ一応確認しましょう。
コマンド入力のところに戻って

```
netvolante-dns get hostname list all
```
![スクリーンショット 2024-05-29 185120.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3795539/7518b22e-14d5-f94d-f944-bea248ddd981.png)
そうすると..
```

コマンド "netvolante-dns get hostname list all" を入力しました。

[ コマンド入力結果(最新の実行ログ) ]
# netvolante-dns get hostname list all

(Netvolante DNS server 1)
PP01    指定したホスト名.aa0.netvolante.jp
# 

コマンドが正常に実行されました。
```
となるはずです
![スクリーンショット 2024-05-29 185236.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3795539/21d62600-6f39-d0ee-d2aa-d40b92f71c1b.png)

## DDNSの設定を消すには
下のコマンドで行けます
```
netvolante-dns delete go pp 1
```
![スクリーンショット 2024-05-29 185316.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3795539/dd0969c5-bd58-9373-961e-a43ef3394e72.png)
すると..

![スクリーンショット 2024-05-29 185358.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3795539/e25c9a02-1da8-3fd3-53ea-62e380e92b1c.png)
こうなったら消えています。
## 追記
初期化しても、Netvolante-dnsは残っちゃいます。その場合は
```
pp select 1
netvolante-dns hostname host pp 指定したいホスト名.aa0.netvolante.jp
netvolante-dns delete go pp 1 指定したいホスト名.aa0.netvolante.jp
```

で消せます(ここら辺はわかりにくいので、コメントしてもらった方がいいかもしれません)
## 最後に
よくわからなかったらコメント欄でお願いします。
## 参照
https://www.iodata.jp/products/plant/2002/npbbrsx/dyndds1.htm

https://network.yamaha.com/setting/router_firewall/other_operation/netvolantedns_operation/netvolantedns-router_exchage#new_command
StudioOneでビデオトラックを非表示にする方法

# 結論
グローバルトラックのメニューから非表示にできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261836/a1aa9b21-a11d-dca5-5246-04fd1e065f3f.png)

調べてもどこにも書いてないし、公式にも記載がなかったので探しました...
同じ人がいるかもしれないので一応。
サービスを作るなら手始めに人を騙せ

# はじめに

**ほとんどの新製品やサービスは失敗します**

あなたは個人開発などで自分のサービスを作って多くの人に使ってもらいたいと考えたことがあるでしょうか？
またはその粋を超えて、起業したいと考えたことがあるでしょうか？

多くの人が**自分自身や自分のアイデアについては、なぜか失敗とは無縁なものだと信じ込みます**

しかし、ほとんどが失敗しているという現実があります。
今回は、「新規事業やサービスを成功させるなら人を騙してデータを集めろ」ということについて紹介していきます

# 優秀な人たちの劇的な失敗

新規事業やサービスを作るときに失敗するのは、「企画・開発から販売までのどこかの段階で何らかの経験や能力不足していたから」そう失敗すると思ってしまうものだが、そんなことはまったくないです

Googleが出したメガネ型ウェアラブルデバイス「グーグルグラス」
ディズニーが多額の販促費をかけた「ジョンカーター」

など経験豊富で有能な人たちが作り出したサービスでも失敗というのは色々存在します。

つまり**経験と能力は、市場に出て売れるか全くデータのない新製品を手がける場合は無意味である**わけです

<font color="red">**モノをつくる前には、そのアイデアがそもそも本当に欲しがられているかを確認する**</font>という工程をやらないといけないです。ここで「人を騙す」という過程を行うことで、本当にそのアイデアは価値があるのかを明らかにできるのです

# 人を騙して検証せよ

「人を騙す」ことでアイデアに価値があるのかを試すことが可能です。この考え方を説明するために実際にIBM社での例を紹介します。

インターネットが普及する前にIBM者は音声認識技術を開発しており、タイピングせずに文字起こしができる技術は大儲けできる可能性があると考えていました。しかし、実際にこのシステムを作るとなると**大金がかかる**ため、実際に作って需要がなかったというのは避けたいことでした。

そこでIBMが行ったのは、コンピュータとマイクを用意して実際に利用してくれそうな人に音声認識技術を試してもらうことにしました。

「こんにちは私は〇〇です」

すると画面には実際に音声入力したことが正確に入力されます。しかし、この実験では**音声認識システムなどは存在しておりませんでした**

隣の部屋で経験を積んだタイピストが控えており、あたかも音声認識したかのような状態を作っていたのです。

**IBMは音声認識システムのプロトタイプを作ったわけでなく、プロトタイプがある"ふり"をしただけだったのでした**

こうすることで**プロトタイプを作る費用すらかけず**に、**実際にアイデアに価値があるのかを検証する**ことが可能になったわけです。

実際にユーザーに試してもらい反応を調査することは新規サービスを失敗する確率を下げることにも繋がりますし、もしお金を払って使いたいという人が現れればより成功率はあがることになります。

つまり、サービスを作る前にアイデアが正しいのかプロトタイプのふりをした「プレトタイピング」(造語)を作ることが大切になるのです

# サービスを失敗させないために

サービスを失敗させないためには、早く市場にリリースして評価のFBをもらうことが大切になります。

プロトタイプを早く作ってリリースするのも大切ですが、ここからの学びはプロトタイプのふりをしたサービスで「人を騙す」というでもFBは得られるということです。

裏の事情を知っていれば「騙している」と思われますが、ユーザーからすれば事実のように思えますし、もしアイデアに価値があればその体験を「騙した」にしないようにアイデアをしっかりと実現すれば問題ないはずです。

もし世の中に新たな価値を作るのであればプロトタイプでも時間やコストなどがかかるので、プロトタイプのふりをしたサービスをとりあえずリリースして素早く検証することはかなり「アリ」で「最適」な選択肢と言えます。

とくにAI系のサービスが増える世の中では、AIのふりをしてまずは人力でやってみるのもよいかもしれません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810513/2f235fcb-7efd-8e13-7d1d-01aa83afe825.png)

(漫画「トリリオンゲーム」では花束をユーザーの情報からレコメンドするようなシステムを人力で最初にやって需要を測るということをしていました)

# おわりに

この方法をすることはユーザーストーリーを更に細かくすることにも役立つと思います。ユーザーがあたかも「機能」を利用できているように見せることができればそれだけでもリリースが可能な単位になります。

そのあと機能を拡充するというストーリーで、実際に機能を作ってリリースすればユーザーとしてはより体験がよくなると感じられます。

このような考え方はとても大切だなと感じたので紹介しました。
私も意識してやっていこうと思います。

ここまで読んでいただけた方はいいねとストックよろしくお願いします。
@Sicut_study をフォローいただけるととてもうれしく思います。

また明日の記事でお会いしましょう！

# JISOUのメンバー募集中！
プログラミングコーチングJISOUでは、新たなメンバーを募集しています。
実践的なカリキュラムで、あなたのエンジニアとしてのキャリアを最短で飛躍させましょう！
興味のある方は、ぜひホームページからお気軽にカウンセリングをお申し込みください！
▼▼▼

https://projisou.jp
個人用PowerShellまとめ

■ヘルプ
help コマンド


■圧縮、展開
Compress-Archive
Expand-Archive

■ファイル削除、コピー
Remove-Item ファイル名
Copy-Item "フルパス" -Destination "ディレクトリパス"

■ファイル名変更
Rename-Item

■検索(ｓｓでユーザー辞書登録)
Select-String 

■再帰的に検索（たぶん）
Get-ChildItem -Recurse | Select-String -Pattern ""

■ファイル名取得(ｇｃでユーザー辞書登録)
(Get-ChildItem -Recurse).fullname

■作成
New-Item



例：フォルダ作成
New-Item -Path "C:\Users\person\Documents\develop\js\sample\trunk\jsbook_my"-Name "chap01" -ItemType "directory"
New-Item -Path "C:\Users\person\Documents\develop\js\sample\trunk\jsbook_my"-Name "chap02" -ItemType "directory"
New-Item -Path "C:\Users\person\Documents\develop\js\sample\trunk\jsbook_my"-Name "chap03" -ItemType "directory"
New-Item -Path "C:\Users\person\Documents\develop\js\sample\trunk\jsbook_my"-Name "chap04" -ItemType "directory"
New-Item -Path "C:\Users\person\Documents\develop\js\sample\trunk\jsbook_my"-Name "chap05" -ItemType "directory"
New-Item -Path "C:\Users\person\Documents\develop\js\sample\trunk\jsbook_my"-Name "chap06" -ItemType "directory"
New-Item -Path "C:\Users\person\Documents\develop\js\sample\trunk\jsbook_my"-Name "chap07" -ItemType "directory"
New-Item -Path "C:\Users\person\Documents\develop\js\sample\trunk\jsbook_my"-Name "chap08" -ItemType "directory"
New-Item -Path "C:\Users\person\Documents\develop\js\sample\trunk\jsbook_my"-Name "chap09" -ItemType "directory"
New-Item -Path "C:\Users\person\Documents\develop\js\sample\trunk\jsbook_my"-Name "chap10" -ItemType "directory"
New-Item -Path "C:\Users\person\Documents\develop\js\sample\trunk\jsbook_my"-Name "chap11" -ItemType "directory"
Azure AI Search のインデックスを Python と JSON 定義ファイルで作成する

Python スクリプトからインデックスを作成しようとしたときに、Azure AI Search の Python SDK を使う方法だとちょっと面倒そうだったので、SDK を使わずに (Azure Portal から入手できる) JSON 形式のインデックス定義ファイルを REST API に投げつける方式でやってみたのでメモ。[^curl]

[^curl]: 「それだけなら curl コマンドとかでいいじゃん」というツッコミがありそうだが、実際にやりたかったのは「インデックス定義を少しいじりつつ複数のインデックスを作成する」だったので、Python から扱えることに意味はあった。

``` python
from os import getenv
import urllib.request

SEARCH_RESOURCE = getenv("SEARCH_RESOURCE")
SEARCH_API_KEY = getenv("SEARCH_API_KEY")
SEARCH_API_VERSION = getenv("SEARCH_API_VERSION", "2024-07-01")


def create_index_from_json(index: str) -> bytes:
    """Azure AI Search のインデックス定義 (JSON 文字列) からインデックスを作成する"""
    url = f"https://{SEARCH_RESOURCE}.search.windows.net/indexes?api-version={SEARCH_API_VERSION}"
    data = index.encode()
    headers = {
        "Content-Type": "application/json",
        "api-key": SEARCH_API_KEY
    }
    try:
        request = urllib.request.Request(url, data, headers)
        with urllib.request.urlopen(request) as response:
            return response.read()
    except urllib.error.HTTPError as err:
        return err.fp.read()
```

``` python
with open("index.json", "rt") as f:
    result = create_index_from_json(f.read())

print(result.decode())
```

参考: [検索インデックスの作成 - Azure AI Search | Microsoft Learn](https://learn.microsoft.com/ja-jp/azure/search/search-how-to-create-search-index?tabs=index-rest)
Javaで「代入演算子」の動作を確認してみた

# 概要

Javaで「代入演算子」の動作を確認してみました。
以下のページを参考にしました。

https://www.javadrive.jp/start/ope/index10.html

# 実装

以下のファイルを作成しました。
```JSample10_1.java
class JSample10_1{
  public static void main(String[] args){
    int num;

    num = 10;
    System.out.println(num);
    num += 5;
    System.out.println(num);

    num = 8;
    System.out.println(num);
    num *= 4;
    System.out.println(num);
  }
}
```
```JSample10_2.java
class JSample10_2{
  public static void main(String[] args){
    int a, b, c;

    a = b = c = 15;
    System.out.println(a);
    System.out.println(b);
    System.out.println(c);
  }
}
```

以下のコマンドを実行しました。
```
$ javac JSample10_1.java 
$ java JSample10_1 
10
15
8
32
```
```
$ javac JSample10_2.java 
$ java JSample10_2 
15
15
15
```

# まとめ

何かの役に立てばと。
[JavaScript] filterメソッドとは

# まとめ

#### `map`メソッドとは
> `filter()` は Array インスタンスのメソッドで、指定された配列の中から指定された関数で実装されているテストに合格した要素だけを抽出したシャローコピーを作成します。
※[mdn web docs](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/filter)

つまり、**`filter`メソッドは、配列の各要素に対して指定した条件を満たすかどうかをチェックし、条件を満たす要素のみを含む新しい配列を返します。**

# 目次
- [基本構文](#基本構文)
- [活用例1](#活用例1)
- [活用例2](#活用例2)
 
# 基本構文
配列`numbers`の値を`num`としてコールバック関数`num => num * 2`に渡し、新たな配列`doubled numbers`として返している。

~~~JS:JavaScript
const numbers = [1, 3, 6, 8, 11];
const lucky = numbers.filter(function(number) {
  return number > 7;
});

console.log(lucky);

//出力結果　[ 8, 11 ]
~~~

# 活用例1
`filter`メソッド内に、`if`文を書いてさらに細かく絞り込んでいます。
以下のコードは、値が偶数のものは除外し、その中で2以上の値だけを抽出しています。

~~~JS:JavaScript
const array = [1, 2, 3, 4, 5]
const newArray = array.filter(function(value) {
  if (value % 2 === 0) {
    return false
  }
  return value >= 2
})

console.log(newArray)

//出力結果　[3, 5]
~~~

# 活用例2
これは`indexOf`を使用し配列に格納されている値のインデックス番号を取得しています。実行結果の左側は`indexOf`メソッドが取得したインデックス番号であり、user2など同じ値がある場合インデックス番号は同じものとなります。
また実行結果の右側は`filter`メソッドが参照しているインデックス番号であり、重複したデータ(`user2`や`user5`)だけ`filter`メソッドが参照しているインデックス番号と同じではありません。そのためこのコードでは被っている値を見つけることができます。

~~~JS:JavaScript
const items = ["user1","user2","user2","user3","user4","user5","user5","user5","user5"];
 
const result = items.filter(function(value, index, array) {
 
 console.log(array.indexOf(value) + ' : ' + index);
 
})

//出力結果
//0 : 0
//1 : 1
//1 : 2
//3 : 3
//4 : 4
//5 : 5
//5 : 6
//5 : 7
//5 : 8
~~~

#### 解説
- `array.indexOf(value)`は、現在の`value`が配列`array`内で最初に出現するインデックスを返します。
- `index`は、現在の`value`が`filter`メソッド内で処理されているインデックスを示します。

#### 処理の流れ
1. `value`が`"user1"`のとき:
   - `array.indexOf("user1")`は`0`を返します。
   - 現在の`index`は`0`です。
   - 出力: 0 : 0

1. `value`が`"user2"`のとき（最初の`"user2"`）:
   - `array.indexOf("user2")`は`1`を返します。
   - 現在の`index`は`1`です。
   - 出力: 1 : 1
1. `value`が`"user2"`のとき（2回目の`"user2"`）:
   - `array.indexOf("user2")`は最初の`"user2"`のインデックスである`1`を返します。
   - 現在の`index`は`2`です。
   - 出力: 1 : 2
1. `value`が`"user3"`のとき:
   - `array.indexOf("user3")`は`3`を返します。
   - 現在の`index`は`3`です。
   - 出力: 3 : 3

# 参考リンク
- [mdn web docs](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/filter)
- [JavaScriptにおける配列のfilter()メソッド](https://www.digitalocean.com/community/tutorials/js-filter-array-method-ja)
- [JavaScriptの配列操作～filterメソッド～](https://it-kyujin.jp/article/detail/544/)
Sonatype Nexus Repository: 安定運用のための重要ポイント

## Sonatype Nexus Repository とは

プロダクトで多数のnpmパッケージを使用しており、稀にネットワークエラーでCI/CDが失敗することがあったため、npmパッケージ等のキャッシュをローカルに持つために、Sonatype Nexus Repositoryを導入しました。
Sonatype Nexus Repositoryは、ビルドアーティファクトや依存関係を一元管理するためのリポジトリマネージャで、以下のような特徴があります。

* **アーティファクトの管理**: ビルドプロセスで生成されたバイナリや依存関係を一元管理できます。
* **リポジトリの統合**: Maven、npm、yumなど、複数のリポジトリ形式をサポートし、一箇所で管理が可能です。
* **キャッシュ機能**: リモートリポジトリのキャッシュを保持し、ビルド時間の短縮やネットワーク負荷の軽減が可能です。

## Sonatype Nexus Repository 運用時のポイント

つまづきや運用ポイントをまとめておきます。

### ストレージに4GB以上の空き容量を確保することが必須

運用初期に以下のようなエラーが発生したことがあります。
```
com.orientechnologies.orient.core.exception.OLowDiskSpaceException: Error occurred while executing a write operation to database ‘component’ due to limited free space on the disk (4092 MB). The database is now working in read-only mode. Please close the database (or stop OrientDB), make room on your hard drive and then reopen the database. The minimal required space is 4096 MB. Required space is now set to 4096MB (you can change it by setting parameter storage.diskCache.diskFreeSpaceLimit)
```
Nexus で採用している *OrientDB* は空き容量が4096 MB必要とのこと。
枯渇するとDBへの書き込みが止まり、リポジトリからのファイル取得等できなくなります。

### クリーンアップポリシーの設定

proxyを使う場合、日に日に増えていくリポジトリのサイズを抑えるために、クリーンアップポリシーを設定することが重要です。
Component Age(キャッシュしてからの経過日数)、Component Usage(最後に使われてからの経過日数)の2つのポリシーがあります。

個人的には、*Component Usage* を採用しています。

日数は30日程度で良いかなと思います。

### Task にクリーンアップを設定

ポリシーを作ったらそのポリシーを実行するためのTaskを作成します。
毎日実行する必要も無いので、週に1回程度で十分かと思います。
以下のように設定し運用しています。

- Task frequency:
  Weekly
- Time to run this task:
  23:00
- Days to run this task:
  Saturday

### Task に Admin - Compact blob store を設定

最近気づいたのですが、クリーンアップのTaskを設定しただけではファイルは物理的に削除されません。
Nexus のドキュメントをみたところちゃんと書いてありました。
https://help.sonatype.com/en/cleanup-policies.html

> A soft delete means that artifacts are only marked for removal and not yet deleted from the disk. Disk space is not reclaimed until the Admin - Compact blob store task runs.

ソフトデリートだから、ファイルは削除されていないと。
*Admin - Compact blob store* のTaskを作成し、実行することでファイルが削除されるということなので、これも設定しておきましょう。
ソフトデリートの後が良さそうなので、以下のように設定して運用しています。

- Task frequency:
  Weekly
- Time to run this task:
  01:00
- Days to run this task:
  Sunday

## まとめ

これらのポイントを押さえて運用すれば、Sonatype Nexus Repositoryを安定して効率的に運用することができます。
僕なりの Composer 備忘録

# 自身のバージョン

```bash
# 最新にアップデート
$ composer self-update
```



# パッケージのバージョン管理

- `MAJOR.MINOR.PATCH`の形式
    - MAJOR: APIの非互換な変更
    - MINOR: 後方互換のある機能追加
    - PATCH: 後方互換のあるバグ修正

- `~`チルダと`^`キャレットがある。



`~`チルダの場合

| 指定   | 意味              |
| ------ | ----------------- |
| ~1.2   | >= 1.2.0, < 2.0.0 |
| ~1.2.1 | >= 1.2.1, < 1.3.0 |

`^`キャレットの場合

| 指定   | 意味              |
| ------ | ----------------- |
| ^1.2   | >= 1.2.0, < 2.0.0 |
| ^1.2.1 | >= 1.2.1 < 2.0.0  |
| ^0.3   | >= 0.3.0, < 0.4.0 |

- ※ 1.0.0未満は開発版と解釈され、PATCHのみしか上がらない



どう使おうか

- 対象アプリケーションを

    - 継続的にメンテナンス可能 → キャレットでPATCH指定。

    - 継続的にメンテナンス不可 → チルダでPATH指定。

    - 絶対触らない → 何も使わずバージョン指定。



> 参考：
>
> https://semver.org/
>
> https://zenn.dev/kazma_13/articles/422ffe9026fd56
[ECS・RDS] AWS CLIを利用して、ECSコンテナからRDSに接続するで！！！

# はじめに
:::note info
- この記事は紆余曲折し、エラーを解消しながらゴールまで突き進む物語です
- 最短の手順だけを述べたものではありません
- 少しでも皆さんのデバッグのヒントになればと思っております
:::


# 目的
掲題の実現

# 前提
- AWS CLI セットアップ済み
- ECS構築済み
- RDS構築済み
    - 今回はMySQLを利用します
- aws-vault設定済み（どちらでも可）

# Systems Managerのパラメータストアに環境変数を用意
パラメータストアにRDSへの接続に必要な環境変数を用意します

![自分のパラメータ_-_AWS_Systems_Manager_-_パラメータストア.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2515002/e309227e-c27c-c479-b049-c7e3ab11aa72.png)
MySQLですと、上記の環境変数を用意します
ホストには作成したRDSのエンドポイントを設定してください

:::note warn
タスク定義でアプリケーションコンテナがパラメータストアから環境変数を参照するようにしておきましょう
:::

# AWS CLIでECSにログインしましょう


以下、コマンドを実行します
```
❯ aws-vault exec sotaheavymetal21 -- aws ecs execute-command \
    --cluster sota-dev-cluster \
    --task 00000000000000000000000000 \
    --container app \
    --interactive \
    --command "/bin/sh"

The Session Manager plugin was installed successfully. Use the AWS CLI to start a session.


Starting session with SessionId: ecs-execute-command-00000000000000000000000
#
```

問題なくアプリケーションコンテナにログインできました

続いて以下のコマンドを実行します

```
apt-get update && apt install -y default-mysql-client
```

MySQLに接続するためには、まずdefault-mysql-clientパッケージをインストールする必要があります
このパッケージには、MySQLに対するクエリを実行するためのクライアントツールが含まれています
具体的には、apt-get updateコマンドを使用してパッケージリストを最新の状態に更新し、
その後にapt install -y default-mysql-clientコマンドを実行してdefault-mysql-clientパッケージをインストールします
インストールが完了すると、MySQLに接続するための準備が整います


接続には、以下のコマンドを実行します
```
mysql -h hostname -u username -p database_name
```

- hostname：MySQLサーバーのホスト名またはIPアドレス（今回はDBインスタンスのエンドポイント）
- username：MySQLユーザー名
- database_name：接続するデータベース名


```
# mysql -h sotaheavymetal21_rds.ap-northeast-1.rds.amazonaws.com -u sotaheavymetal21 -p sotaheavymetal21_db
Enter password:
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 2021
Server version: 8.0.35 Source distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [sotaheavymetal21_db]>
```

接続を確立すると、MySQLクライアントが起動し、SQLクエリを実行することができます！





# おわりに
お疲れ様でした！！
試行錯誤しながらの記事になっております
少しでも皆さんのお力添えになればと思っています🐰

# 参考

https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/CHAP_CommonTasks.Connect.html
Salesforce ApexでSite.createExternalUser()が失敗

Site.ExternalUserCreateException
[この要求の処理中に不明なエラーが発生しました。]
(System Code)

とかになる

パスワードルールに反したパスワードを指定しているとなるっぽい
ユーザ名の@より前をパスワードに含めているとか

ちなみにトリガやテストコードではSite.createExternalUser()は使えないっぽい
(nullが返ってくるっぽい)
僕なりの Yaml 備忘録

# 複数行の記載パターン

```yaml
# 改行で区切り
foo1: |
    test1
    test2
	
# 改行で区切り（最後の改行を削除）
foo2: |-
    test1
    test2
	
# 半角スペースで区切り
foo3: >
    test1
    test2
	
# そのまま結合
foo4: "\
    test1\
    test2\
    "
```
【随時更新】フォーマット兼Markdown記法 チートシート

# 目的
メモ
# 結論
メモ
# 解説
メモ

# 参考
[Markdown記法 チートシート](https://qiita.com/Qiita/items/c686397e4a0f4f11683d "Markdown記法 チートシート")

# メモ
・
・
・
・
・
# Markdown記法 チートシート
## 順序無しリスト
-
-
-
「*」or「+」or「-」+「半角スペース」

## 番号付きリスト
1. テスト
1. テスト
1. テスト

「数字.」+「半角スペース」 

## チェックボックス
- [ ] タスク1
- [x] タスク2



## 水平線
* * *
***
*****
- - -
---------------------------------------
```
* * *
***
*****
- - -
---------------------------------------
```



## リンク
[Qiita](http://qiita.com "Qiita Home")


## コードユニット
```Python:test.py
print("test");
```

## diff
```
- print("test");
+ print("test123");
```

# italic type
_ か * で囲む *italic type* 

# 太文字
__ か ** で囲む **太字** 

## 打ち消し線
 ~~ で囲む。 ~~打ち消し~~

## インライン表示
`puts 'Qiita'` 

## タイトルありの画像を埋め込む
![Qiita](https://qiita-image-store.s3.amazonaws.com/0/45617/015bd058-7ea0-e6a5-b9cb-36a4fb38e59c.png "Qiita")
'''

## テーブル
3x2
| 1 | 2 | 3 |
|:-:|:-:|:-:|
| a | b | c |
| d | e | f |



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

:::note warn
警告
○○に注意してください。
:::

:::note alert
より強い警告
○○しないでください。
:::

## 引用
> 文頭に>を置くことで引用になります。
> 複数行にまたがる場合、改行のたびにこの記号を置く必要があります。
> **引用の上下にはリストと同じく空行がないと正しく表示されません**
> 引用の中に別のMarkdownを使用することも可能です。
> 
> > これはネストされた引用です。
【Streamlit】集合棒グラフを作って日付ごとの売上見込・売上実績を比較する

# 前置き
こんにちはデータエンジニアの山口歩夢です！

この度、Streamlitの入門書を執筆しました！
Streamlitについて、基本的な内容から実践的な内容、自分が開発する上で躓いたポイントやTipsなどを書かせていただきました。

電子版が技術書典にて購入可能なため、是非チェックいただけると幸いです。

https://techbookfest.org/product/t5GBwbFm4kUhXrTPkGpAnY?utm_source=twitter&utm_medium=social&utm_campaign=share

今回は、Streamlitで集合棒グラフを作成したので、作成方法をご紹介させていただきます。

# 集合棒グラフとは
集合棒グラフ(grouped bar chart)とは、複数のカテゴリのデータを比較するためのグラフです。各カテゴリが棒で表され、高さがそのカテゴリの数値を表します。
棒グラフは一つのカテゴリの値を期間ごとに比較したりするのに役立つのに対して、集合棒グラフは複数のカテゴリを期間ごとに比較するのに役立ちます。

以下のようなグラフです。
売上実績と売上見込が隣合わせになり、日付ごとに集計されていることが分かります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/883573/c7ba5668-d752-e607-ca57-d48c4448a6bb.png)

# 実装方法
`Vega-Altair`というPythonのデータ可視化ライブラリと、`st.altair_chart`というStreamlitに用意されている関数を使用して、集合棒グラフの作成を行います。

`st.altair_chart`は、`Vega-Altair`ライブラリを使用してデータを可視化してくれる関数です。
Streamlitには`st.bar_chart`や`st.line_chart`などの非常に簡単なコードでデータを可視化できる関数が用意されていますが、これらは`st.altair_chart`を使う場合よりも簡単にコードを書けるようにした関数(syntax-sugarと呼ばれる関数)です。
今回の集合棒グラフのようなカスタマイズ性が高いグラフを可視化したい場合は、`st.altair_chart`の方を使用する必要があります。


上記のライブラリや関数を使用して作成したコードは以下です。

```streamlit_app.py
import streamlit as st
import pandas as pd
import altair as alt
import numpy as np

st.set_page_config(
    page_title="Streamlit App",
    page_icon="🧊",
    layout="wide",
    initial_sidebar_state="expanded"
)

# 日付範囲を生成
date_range = pd.date_range(start='2024-05-01', periods=15, freq='D')

# 売上見込と売上実績のデータをランダムに生成
sales_forecast = np.random.randint(100, 300, size=15)
sales_actual = np.random.randint(80, 250, size=15)

# データフレームを作成
data = pd.DataFrame({
    '日付': date_range,
    '売上見込': sales_forecast,
    '売上実績': sales_actual
})

# 日付列を文字列に変換
data['日付'] = data['日付'].dt.strftime('%Y-%m-%d')

# グラフ化するためにデータ型を更新
data_long = pd.melt(data, id_vars=['日付'], value_vars=['売上見込', '売上実績'])

# Altairチャートを作成
chart = alt.Chart(data_long).mark_bar(
    opacity=1
    ).encode(
    column=alt.Column('日付:O', spacing=5, header=alt.Header(labelOrient="bottom", title=None)),
    x=alt.X('variable', sort=['売上見込', '売上実績'], axis=None),
    y=alt.Y('value:Q', title=None),
    color=alt.Color('variable', title=None)
).configure_view().properties(width=60, height=400)

# Streamlitにチャートを表示
st.altair_chart(chart)

```
上記のコードを書いて、「streamlit run」を実行すると
```cl
$ streamlit run streamlit_app.py
```

以下のように、集合棒グラフを作成することができました！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/883573/c7ba5668-d752-e607-ca57-d48c4448a6bb.png)


# まとめ
Streamlitには、`st.bar_chart`や`st.line_chart`などの簡単にグラフを可視化できる関数を用意されていますが、
`st.altair_chart`を使用することで更に複雑なグラフを可視化できるということが非常に勉強になりました！
知らないと料金発生！？AWS無料枠での注意点3選

AWSには一年間の無料利用枠があります。プログラミング学習をされている方の中には、これを利用してAWSを勉強されている方も多いのではないのでしょうか？

ただしこの無料枠もすべてなわけではなく、使い方によっては料金がかかってしまいます。私も気づかない間に、料金が発生してしまっていました。

なので今回は同じようにAWSを学習している人に向けて、料金が発生しないように注意してほしいこと3つを紹介します！

## AWS無料枠とは
AWSの無料枠は、AWSのプラットフォーム・製品・サービスを無料で実際に体験できる枠組みです。ビジネス用途としては物足りない内容となっていますが、学習目的であればこの無料枠でいろいろ学ぶことができます。AWS無料枠の対象サービスは100以上あります。その中で使用するサービスにより、「12か月間無料」「常に無料」「トライアル」の3つに大別されます。

[>> 無料枠に関するAWS公式ページ](https://aws.amazon.com/jp/free/?all-free-tier.sort-by=item.additionalFields.SortRank&all-free-tier.sort-order=asc&awsf.Free%20Tier%20Types=*all&awsf.Free%20Tier%20Categories=*all)

### AWS無料枠：「12か月間無料」
「12か月間無料」は AWSに最初にサインアップした日から12か月間、AWSのサービスを無料枠内であれば無料で利用できます。こちらのサービスの代表例として、クラウドコンピューティングサービスの「EC2」やオブジェクトストレージサービスの「S3」・リレーショナルデータベースサービスの「RDS」といったAWSの中でも代表的なサービスが対象です。

### AWS無料枠：「常に無料」
「常に無料」は無料利用枠に有効期限がなく、AWSのすべての方が無料で利用できます。ただこちらは有効期限はないですが無料利用枠はあるので、その点はご注意ください。こちらのサービスの代表例は、NoSQLデータベースサービスの「DynamoDB」や自動コンピューティングサービスの「Lamda」があります。

### AWS無料枠：「トライアル」
「トライアル」はサービスを最初に利用した日から、決められた期間の間は無料で利用することができます。無料のトライアル期間が終了すると、標準の従量制料金を支払う必要があります。こちらのサービスとしては、分析などで使用される「RedShift」などがあります。

## AWS無料枠の注意点3選
もし無料期間内で料金が発生してしまわないように、以下の3点をチェックしていただきたいです。私はこれらのミスにより、料金が発生してしまっていました。

- **EC2インスタンスをたくさん作らない**
無料でrunnninng状態で起動できるのは最大750時間まで
- **RDSは1つだけ**
RDSもEC2と同様で、無料枠で利用可能なのは750時間まで
- **EIPはEC2インスタンスに紐付ける**
EC2に紐付けずに、作成して放置していると料金が発生

[>> 注意点についてより詳しい解説はコチラ！](https://taishi-official.com/2020/05/22/502/#toc5)

## まとめ
以上がAWSで無料枠を使って勉強する際に、気をつけてほしいことでした。これまで述べたように、注意していないと料金がかかってしまいます。

しかしAWSを使ったクラウドシステムは、これからのIT業界には欠かせないスキルです。**多少お金を払うリスクがあっても、絶対に学んでおいたほうがいい**と思います。

**こまめに請求書をチェック**していれば、それほど高い料金は請求されないと思います。（私の場合は1500円程度で済みました）リスクを恐れず、無料枠を使って勉強していきましょう❗

### おまけ

https://qiita.com/taishi_will_be/items/70a8ce8938944286b487

https://taishi-official.com/learning-programming/

<strong>＼Follow me／</strong>

- X（旧Twitter）：https://x.com/taishi_it_blog
- Instagram：https://www.instagram.com/taishi_will_be/
- YouTube：https://www.youtube.com/@Engineer_ILLBE
- TikTok：https://www.tiktok.com/@taishi_will_be
- note：https://note.com/taishi_wii_be/

<br>

最後にいいねお願いします:thumbsup:
SQLで文字列型の数字項目をOrderByする際の問題と解決策

## 問題の発生理由

SQLにおいて、`ORDER BY`句を使用して文字列型の数字項目を並び替えると、数値としてではなく文字列として比較されます。これにより、意図した通りに並び替えが行われないことがあります。

例として、以下のような文字列型の数字があるとします。

```
'1', '10', '2', '20'
```

このデータを`ORDER BY`で並び替えると、以下のようになります。

```
1, 10, 2, 20
```

これは、数値の大小関係ではなく、文字列としての並び順に基づく結果です。

## 解決策

この問題を解決するには、文字列型の数字項目を数値型に変換してから並び替えを行います。これにより、数値としての大小関係に基づいた正しい並び順になります。

### 例1: MySQLの場合

MySQLでは、`CAST`関数や`CONVERT`関数を使用して文字列を数値に変換できます。

```sql
SELECT *
FROM your_table
ORDER BY CAST(numeric_column AS UNSIGNED);
```

または

```sql
SELECT *
FROM your_table
ORDER BY CONVERT(numeric_column, UNSIGNED);
```

### 例2: PostgreSQLの場合

PostgreSQLでは、`::integer`を使用して文字列を数値に変換できます。

```sql
SELECT *
FROM your_table
ORDER BY numeric_column::integer;
```

または、`CAST`関数を使用することもできます。

```sql
SELECT *
FROM your_table
ORDER BY CAST(numeric_column AS integer);
```

### 例3: SQL Serverの場合

SQL Serverでは、`CAST`関数を使用して文字列を数値に変換できます。

```sql
SELECT *
FROM your_table
ORDER BY CAST(numeric_column AS INT);
```

または

```sql
SELECT *
FROM your_table
ORDER BY CONVERT(INT, numeric_column);
```

## まとめ

文字列型の数字項目を`ORDER BY`で並び替える際には、数値型に変換することで意図した通りの並び順を実現できます。データベースによって使用する関数が異なるため、自分の環境に応じた方法を選択してください。

このようにすることで、文字列としてではなく数値として正しく並び替えが行われるようになります。
性能測定

# いろんな要素の性能を把握する
現実のシステムにおいては、多くの場合、それ以外の`ソフトウェアやネットワークなど別の要素の性能も考慮`する必要があります。
...
プログラマは各処理に必要な時間を計測できるようにしておく必要がありますし、`システムの運用管理者はそのログのありか、および見方を知っておく必要`があります。

# 性能測定の目的を明確にする
目的がなければ結果を何にも生かせないので、単なる時間の浪費になってしまいます。
目的を決めてからも、```どういうパターン```で性能測定するのか、そのために```どういうベンチマークツール```を使うかを決めなければなりません。性能測定は所要時間が長くなる傾向があるので、なるべく「あれもこれも」と余計なデータは取らずに、目的を達成するための```必要最小限のデータ```だけを取るように心掛けましよう。

# 出典
https://gihyo.jp/book/2022/978-4-297-13148-7

# 感想
目的を明確にしないとどれも作ることができない。
RHEL8 (ppc64le) で queue_depth を恒久的に変更するには

#### はじめに

RHEL on Power において queue_depth の値を変更する必要があり、確認したログです。

POWER10 のマニュアルには以下が案内されていますが、リブートすると消えてしまうため、恒久的に設定する方法を確認していました。

https://www.ibm.com/docs/ja/power10/9080-HEX?topic=storage-changing-virtual-scsi-queue-depth

> hdiskN は物理ボリューム名を表し、value は 1 から 256 の範囲内でユーザーが割り当てた値になります。
クライアント論理区画上の Linux クライアント論理区画のキュー項目数を変更するには、次の例のように echo コマンドを使用します。

> echo 16 > /sys/devices/vio/30000003/host0/target0:0:1/0:0:1:0/queue_depth


---

#### 参考

https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/8/html/managing_storage_devices/setting-the-disk-scheduler-using-udev-rules_setting-the-disk-scheduler


-> /etc/udev/rules.d/ 下に設定ファイルを作成します。

<br>

ppc64le で以下のudev rules の記載を参考にしました。

https://www.ibm.com/docs/en/ess-p8/5.3.7?topic=guide-os-tuning-rhel-79-ppc64le-protocol-nodes

> udev rules for RHEL 7.9 PPC64LE protocol nodes

> ACTION=="add|change", SUBSYSTEM=="block", KERNEL=="sd*[^0-9]", 
PROGRAM="/usr/bin/lsblk -rno FSTYPE,MOUNTPOINT /dev/%k", RESULT=="*[SL][WV][AM][P2]*", 
ATTR{device/vendor}=="ATA", ATTR{queue/nr_requests}="64", ATTR{device/queue_depth}="32"
ACTION=="add|change", SUBSYSTEM=="block", KERNEL=="sd*[^0-9]", 
PROGRAM="/usr/bin/lsblk -rno FSTYPE,MOUNTPOINT /dev/%k", RESULT=="*[SL][WV][AM][P2]*", 
ATTR{device/vendor}!="ATA", ATTR{queue/nr_requests}="128", ATTR{device/queue_depth}="64"


---

#### 環境

RHEL8.6 ppc64le (VIO Client) on S1014

・vscsi(virtual scsi)、NPIV(N-Port ID Virtualization)のどちらの環境も同じ方法でqueue_depthの設定反映が確認できました。

---

#### 設定、確認


・対象のデバイスの現在の queue_depth を確認

```
# udevadm info --attribute-walk --path=/sys/devices/vio/30000002/host0/target0:0:1/0:0:1:0 | grep queue_depth
    ATTR{queue_depth}=="16"

# udevadm info --attribute-walk --path=/sys/devices/vio/30000003/host1/target1:0:1/1:0:1:0 | grep queue
    ATTR{queue_depth}=="16"

```

デフォルト値の 16 の設定が確認できます。


<br>


・/etc/udev/rules.d/ に ルールズ・ファイル 99-scsi-queue-depth.rules を追加


試行錯誤で、実施した環境では以下の内容で変更されることを確認しています。


```99-scsi-queue-depth.rules
ACTION=="add|change", SUBSYSTEM=="block",  ATTR{device/queue_depth}="32"
```


・OS再起動で反映を確認

```
# reboot
```


再起動後、設定値を確認



```
# udevadm info --attribute-walk --path=/sys/devices/vio/30000002/host0/target0:0:1/0:0:1:0 | grep queue_depth
    ATTR{queue_depth}=="32"

# udevadm info --attribute-walk --path=/sys/devices/vio/30000003/host1/target1:0:1/1:0:1:0 | grep queue_depth
    ATTR{queue_depth}=="32"
```

queue_depth がデバイス単位で 32 に設定されたことが確認できました。

----

#### おわりに

この設定は別環境の場合は、設定ファイルの書き方などが異なる可能性があります。

<br>

以上です。
Pythonで学校のチャイムを作成する

## はじめに
怒らないから在宅勤務でさぼってるやつ集まれ。
あの日を思い出せ！数分置きにチャイムを鳴らしてやるよ。

## コード
```py
import time
import datetime
import winsound # Windowsさん
import os # Macさん

def paly_chime():
    # windowsさん
    winsound.Beep(440, 1000)

    # Macさん
    #os.system('say "Chime"')

# スケジュールの設定（指定した時間にチャイムが鳴る）
schedule = [
    (9, 0), (10, 30), (10, 40), (12, 0),
    (13, 0), (14, 30), (14, 40), (16, 0),
    (16, 10), (17, 0), (17, 10), (18, 0)
]

while True:
    now = datetime.datetime.now()
    current_time = (now.hour, now.minute)

    if current_time in schedule:
        play_chime()
        time.sleep(60)

    time.sleep(1)
```

Macのsay "Chime"かっこよくね。ずる。

## おわりに
仕事しろ。
ブロック層の変化

# SSD
データを`フラッシュメモリに保存`します。読み出しも書き込みもHDDのような機械的な動作が一切必要なく、電気的な動作だけで済みます。従って、一般にHDDよりも高速にアクセスできます。

# SSDの種類
接続方式によって２種類に分けられます。
`HDDと同じインターフェースでマシンに接続できる`、いわゆるSATA SSDやSAS SSDと呼ばれるもの
`全く異なる高速なインターフェースで接続できる`NVMe　SSD

# CPUとSSDでIOPSが高くなる
NVMe SSDは、HDDと比べて、ハードウェア性能として文字通り桁違いのIOPSが出せます。高いIOPSを出すには、なるべく`多くの論理CPUから同時並列にI/Oを発行するのが効果的`です。
昨今のCPuの多コア化によって、こうするための条件は揃っているのでは無いかというと、実はそうではありません。過去のI/Oスケジューラは、せっかく`複数論理CPUからリクエストがきても、その処理は一つの論理CPU上で実行していたため、スケーラビティがなかった`のです。この欠点を克服するため、現在のI/Oのスケジューラはマルチキューという仕組みを使って`複数CPUで動作させることによって、スケーラビティを向上`させています。

# ハードウェア性能向上によるブロック層の変化
ハードウェア性能が上がれば上がるほど、`ブロック層においてI/O要求を一旦溜めてI/Oスケジューラによって並び替えるという処理のメリットに対してレイテンシが高くなる`というデメリットが上回るケースが増えてきました。

# 出典
https://gihyo.jp/book/2022/978-4-297-13148-7

https://wa3.i-3-i.info/diff175cpu.html

https://wa3.i-3-i.info/word18079.html
# 感想
この前の実験をしたかったが、pythonのことを理解できていないのでできなかった。
ブロック層がハードウェアの進化に足を揃えればいいのかな。
Pearson VUEのオンライン試験でのシステムテストを突破したい（Windowsの巻）

# Pearson VUEのオンライン試験でのシステムテストで👇のように出る場合


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3346590/3931f03a-ba57-4422-eedd-811c4986dd17.png)
[**vmwp**]_なるタスクが邪魔しているとか表示されます_

## 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3346590/6e99eca5-6a61-9807-914d-fc41c3ee358a.png)
タスクマネージャーで見ると**仮想マシンワーカープロセス**なのですがここで終了させようとしても
消えてくれない問題です
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3346590/df760f2c-7b7a-c6c8-4343-ce1e1fb0c0d0.png)

## ①wsl --shutdown
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3346590/f697acdb-5a14-44f9-15f6-e98059b05202.png)
CMDまたはPowerShellからWSL(Windows Subsystem for Linux)をシャットダウン

## ②WSA (Windows Subsystem for Android)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3346590/13e61f03-2b87-d4ae-90d7-5c28c3a9e2f2.png)
Windows Subsystem for Androidをタスクマネージャーから終了
私は今回こちらだった模様

③Docker停止
私はインストールしていなかったため引っ掛かりませんでしたがDockerの場合もある模様

https://qiita.com/Kotter/items/b694f0ef6bccb239eeca


## おまけ
ネットワークチェックにもひっかかりました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3346590/a10addc5-b317-d2ef-6cd8-df39ee84a309.png)
アクセスコード取得からやりなおすと通りました。
どうみてもネットワークじゃなさそうな時はお試しを。

https://qiita.com/ahir0ta/items/0c0727dd28221bd1cf52
[Route53・ACM・CloudFront] サブドメインをきり、SSL証明書を発行し、CloudFrontの代替ドメインに登録する

# はじめに
:::note info
- この記事は紆余曲折し、エラーを解消しながらゴールまで突き進む物語です
- 最短の手順だけを述べたものではありません
- 少しでも皆さんのデバッグのヒントになればと思っております
:::



# 目的
掲題の実現


# 前提
- サブドメインを切る元のドメインを所有している


# Route53でホストゾーンを作成しましょう

![貼り付けた画像_2024_05_29_17_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2515002/52163459-bfe6-7d11-0b73-30d79f96b4e5.png)


### NSタイプのレコードとは
- NS（ネームサーバー）タイプのレコードは、特定のドメインに対してどのネームサーバーが権威を持っているかを指定します
- これにより、DNSクライアントはドメインのDNS情報を取得するためにどのサーバーに問い合わせるべきかを知ることができます
- Route 53では、ドメインをホストするために自動的にNSレコードが設定されます

### SOAタイプのレコードとは
- SOA（Start of Authority）タイプのレコードは、DNSゾーンの開始点と管理情報を提供します
- このレコードには、ゾーンのプライマリネームサーバー、管理者のメールアドレス、シリアル番号、リフレッシュ間隔、再試行間隔、有効期限、および最小TTLが含まれます
- Route 53では、各ホストゾーンに対して1つのSOAレコードが自動的に作成されます


# ドメインのホストゾーンの中のレコードにサブドメインのレコードを作成します

今回のレコードタイプはNSですので、A⇨NSに変更します
値には先ほど作成したホストゾーンのNSタイプのレコードのネームサーバーを登録します

![dp-playground_pj100_biz_-_レコードを追加.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2515002/f09736e1-18fb-5f95-b3f5-eee07c436e61.png)


# ACMでSSL証明書をリクエストします
リクエスト後のステータスは保留中の検証となっています


![証明書の詳細___708f241d-8fe1-4fee-8c50-0c2a2af84462___Certificate_Manager___ap-northeast-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2515002/904f1551-3ef7-15e7-9f10-b9c02a98ed20.png)


さらに、CNAME名とCNAME値をRoute53に登録する必要があります
`Route53でレコードを作成`から簡単に登録することができます

![証明書の詳細___708f241d-8fe1-4fee-8c50-0c2a2af84462___Certificate_Manager___ap-northeast-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2515002/9ca9120b-5ad4-35c1-1337-9dfc22a5275e.png)


登録してから数分経過後、ステータスが発行済みになりました！
![Cursor_と_証明書の詳細___708f241d-8fe1-4fee-8c50-0c2a2af84462___Certificate_Manager___ap-northeast-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2515002/8c821ca0-84b7-3469-124f-120b4366efdb.png)

:::note warn

CloudFrontのディストリビューションの設定で代替ドメイン名を使用するときに設定するCustom SSL certificate - optionalで、先ほど取得したSSL証明書を利用しても表示されません

:::


理由は東京リージョンで作成しているからであり、バージニア北部リージョンに証明書を作成する必要があります

> AWS Certificate Manager から証明書を関連付けます。証明書は、米国東部 (バージニア北部) リージョン (us-east-1) にある必要があります。
注意書きにあるようにバージニア北部リージョンに証明書を作成する必要があります


![Cursor_と_CloudFront___Global.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2515002/3e27e9bd-c033-8f2b-7e2e-14e94345535e.png)


バージニア北部リージョンで作成すると、問題なく表示されます！
登録すると、このように設定に代替ドメイン名が表示されます

![CloudFront___Global.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2515002/ae6bf7c8-cb0c-b6ad-532a-1e066f3a7236.png)



# 終わりに
お疲れ様でした！！
試行錯誤しながらの記事になっております
少しでも皆さんのお力添えになればと思っています🐰
Amplifyで既存環境を基に新しい環境を構築するスクリプト

## はじめに
Amplifyの環境をとある周期で再作成しているのですがいちいちCLI叩いてってのが面倒になったのでほぼ自動化しました。雑に作っているので使うなら勝手にアップデートしていってください。
今回のスクリプトは環境の追加～デプロイまでを行います。

## 前提
- Amplify cliをインストール済み
- GitでAmplifyのソース管理をしている

## コードところどころ解説
文字化け回避です。
いらないでしょって？確かにな。
```bash
export LANG=en_US.UTF8
```

ENV_NAMEに記載した名前で環境が構築されます。
※スクリプトを実行するときの引数にENV_NAMEを入れてもいいかもしれないですね。
ちなみにこれを実行するとプロファイルを聞かれるのであなたの環境に適したものを選択してください。
```bash
amplify env add "$ENV_NAME"
```

結果の成功失敗を知りたいならこれ書いておけばいいです。マジで。
```bash
if [ $? -ne 0 ]; then
  echo "Error: add env failed."
  read -p "Press any key to continue..."
  exit 1
```

作成した環境に切り替えます。
```bash
amplify env checkout "$ENV_NAME"
```

はい、デプロイ。
```bash
amplify push --yes
```
--yesはコマンドの実行で出てくる選択肢すべてにyesを選択するというオプションです。

## 全体コード
```bash
#!/bin/bash

export LANG=en_US.UTF8

ENV_NAME="hogehoge"

echo "Amplify add env..."
amplify env add "$ENV_NAME"
if [ $? -ne 0 ]; then
  echo "Error: add env failed."
  read -p "Press any key to continue..."
  exit 1

echo "env add Complited"
echo "env checkout..."

amplify env checkout "$ENV_NAME"
if [ $? -ne 0 ]; then
  echo "Error: checkout env failed."
  read -p "Press any key to continue..."
  exit 1

echo "env Checkout Complited"
echo "env deploy..."

amplify push --yes
if [ $? -ne 0 ]; then
  echo "Error: env deploy failed."
  read -p "Press any key to continue..."
  exit 1

echo "env deploy Complited"
read -p "Press any key to continue..."

```

## おわりに
全然手動で一個一個やるのも面倒ではないんだけどね。
勝手にやってくれるならそれはそれでよき。
【図解】SAPBTP環境で販売伝票作成アプリ作ってみた

# SAPチュートリアルを参考に作成
今回はSAPのチュートリアルを通して、販売伝票作成アプリを作ったのでその共有です。

基本的には下記のチュートリアルを実行していけばできる内容となります。
https://developers.sap.com/mission.build-workshop-sales-order.html

作成するにあたってのエビデンスをペタペタと貼っていってもいいのですが、図を作成したほうが自分的にも理解が深まると思ったので作成してみました。

理解しきれていない部分やバックエンドの動きは書ききれていないのですが、トライする際は参考にしてみてください。

チュートリアルのアプリ作成までの内容となります。

# 図:SAPの販売伝票作成アプリ
![sapsalesorder.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821335/e4819427-a492-bc16-3538-22e33db0eddc.png)

アプリ自体はシンプルです。

入力は顧客名、素材、量、配達期日を入力して承認フローに回すというものです。

画面は2つ構成でもう一つの画面でワークフローのステータスが確認できます。

# Sales Order Management→order processing
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821335/b02d2722-ea4e-9a11-2130-8969300dcc95.png)

Sales Order Managementプロジェクトの中にあるorder processingのプロセスはこんなかんじになっています。

基本的には自動承認になって承認フローは終了です。

しかし、10000個を超える場合のみ確認するために承認フローが続きます。

承認と拒否のフローでまた分岐しています。

# Create sales Order
先程のは承認フローの流れでしたが、アプリの画面や認証方法、データ連携などはBuild AppsでCreate sales Orderを作成しております。

## Sales Order Workflow
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821335/87f4bba1-1382-f8f0-9e05-ba5588733724.png)

何のデータを取り込むのか、ボタンを押したときはどうなるかなどはここで設定していきます。

その設定するもととなる部分はDATAと呼ばれる画面で構築していきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821335/756f615f-61de-7e8d-863c-d3dc56b092a1.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821335/cbfa2f2a-6dfd-4dec-20af-7fce8bebef92.png)


DATAで定義したものをUI CAVASでボタンに設定いく流れですね。

画面に見えているのはデバイスストレージとSAPシステムとの連携設定です。

ボタンを押したときどうなるのかといったようなフローはUI CANVASの方で制御可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821335/172421b1-49e7-ccf1-b494-a4b0cf8cc882.png)

## Workflow Status
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821335/6e70da9a-a6dd-805d-6e77-16e57139cc97.png)

同じくWorkflow Statusもボタンを押して情報更新するときのフローはUIの方で制御しています。

Sales Order WorkflowもWorkflow StatusもCreate sales Orderアプリの中で定義されていますので、
DATAタブで定義した情報は流用可能です。


# まとめ
今後はこの作成したアプリをデプロイして、SAP Work Zoneへと展開していきます。
今回実施した内容はSAPのトライアル版で全て可能ですので、時間のある方はトライしてみてください。

注意点はコードなどをコピペする際にリッチテキストのまま認識されるので、メモ帳などに一度コピペしてから再度アプリに反映させたほうが良いです。
特定の子要素（Button）のみを右詰めで配置する

# はじめに
今回は**特定の子要素において、直接プロパティを指定する**方法を試したのでメモしておきます。
UIライブラリはYamada UIを使用しています。

以前「ボタンを中央に配置する方法」をまとめたのですが、**親要素に対してプロパティを指定**していました。

https://qiita.com/AK_React/items/803a6a0eff7b9d8e3a27
# 具体例
今回は**ボタンのみを右詰めで配置**してみます。

```tsx:tsx
<Button type="submit" color="white" ml="auto" display="block"> つぶやく </Button>
```

**margin**：**子要素の周囲のスペースを設定**します。
今回は`margin-left: auto`を使用して、子要素を右詰めに配置します。

**display="block"**： **要素をブロックレベル要素として指定**します。
上記のマージンを指定するためには必要です。
　
# おわりに
CSSはしっかり勉強したことがないので、親要素・子要素という基本的な概念もそこまで意識できていませんでした。
今後も定期的に学びがあれば投稿していきます。
# 参考
https://developer.mozilla.org/ja/docs/Web/CSS/margin

https://developer.mozilla.org/ja/docs/Web/CSS/display
TanStack Query？何それ？

# TanStack Queryとは？
TanStack Queryとは、以前（バージョン3まで）はReact Queryと呼ばれていましたがバージョン4になり名称がTanStack Queryとなりました。
以前まではReact専用のライブラリでしたが、バージョンアップしてからはReactだけではなくSolid, Vue, Svelteなどでも利用できるようになりました。

TanStack Queryはデータフェッチライブラリで、APIからデータを取得したい時や更新したい時に使います。
また、取得したデータはキャッシュされ、キャッシュされたデータを取り出すことも可能です。

# 使い方
## 下準備編
1. 以下コマンドでインストールを行います。

    ```bash
    # npmの場合
    $ npm i @tanstack/react-query
    
    # yarnの場合
    $ yarn add @tanstack/react-query
    ```
2. TanStack Query を利用するコンポーネントを`QueryClientProvider`で囲みます。

    ```react
    import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
    import CoreConcepts from "./core-concepts/page";
    import { Route } from "@/app/type";
    
    const queryClient: QueryClient = new QueryClient({
      defaultOptions: {
        queries: {
          refetchOnWindowFocus: false, // デフォルトでコンポーネントにフォーカスが当たるとフェッチするのを無効化
        },
      },
    });

    function MyApp({ Component, pageProps }: AppProps) {
      return (
        <QueryClientProvider client={queryClient}>
          <App />
        </QueryClientProvider>
      );
    }
    ```

## useQuery編
データ取得には、`useQuery`を使います。
queryKeyとqueryFnオプションにキャッシュ識別のためのkeyとデータフェッチのための関数を渡すだけです。

```react
const { isLoading, data } = useQuery({
  queryKey: ['任意の文字列'] // 配列（空の場合は実行されない）
  queryFn: hogeFugaFetch // データ取得関数(アロー関数をそのまま渡すことも可能)
});
```

## useMutation編
データの追加や変更を行う際には`useMutation`を使います。
フォーム入力データなどを受け取ってAPIに渡したい場合は、アロー関数で引数を渡す。

```react
// 
const mutationWithArg = useMutation({
  mutationFn: (formData) => updateHoge(formData) // データ更新関数
});

// サブミットで受け取ったformDataをmutateメソッドを使って渡してあげる
const onSubmit = (formData) => {
    mutationWithArg.mutate(formData);
};
```

## useQueryClient & getQueryData編
キャッシュされたデータを取り出すには`useQueryClient`フックと`getQueryData`メソッドを使います。

useQueryClientフックは、その時点のQueryClient取得し、この中のキャッシュされたデータやdefaultOptionsの設定情報などを取り扱うことができます。
QueryClientクラスのgetQueryDataメソッドを使ってキャッシュされたデータを取得します。

```react
const queryClient: QueryClient = useQueryClient();
const data = queryClient.getQueryData(['取り出したいqueryKey']);
```

# 参考
[TanStack Query](https://tanstack.com/query/latest)
[TanStack Queryとは？](https://zenn.dev/taisei_13046/books/133e9995b6aadf/viewer/573083)
[TanStack Queryを使ってみる](https://zenn.dev/azunasu/articles/04f24e147ee937)
[TanStack Query v5 入門](https://qiita.com/Yasushi-Mo/items/16144482c8a78c0d6e97)
[初めてでも安心TanStack Query v5の基本的な設定方法と動きを学ぶ](https://reffect.co.jp/react/tanstack-query-v5)