OmniAICreator/Qiita-1.07M huggingface dataset:
SQLを含めたユニットテストにgo-mysql-serverが便利

go-mysql-serverは、ピュアGoで書かれたMySQL互換のインメモリDBです。 READMEにあるようにサーバとして起動することもできますが、 database/sql/driverのDriverも用意されているので、プロセス内で完結することもできます。

このインメモリDBをいろいろなORMと組み合わせてユニットテストで使う方法を紹介します。
...

http://makiuchi-d.github.io/2023/08/12/go-mysql-server.ja.html
Cygwin環境でDockerを快適に使うために

この記事は2018年4月22日に技術書典4にて頒布した「KLabTechBook Vol.2」に掲載したものです。 当時のまま転載しているので現在では適さない部分もあります。
...

http://makiuchi-d.github.io/2023/06/04/klabtechbook2-cygwin-docker.ja.html
Go Conference登壇、そしてGoにジェネリクスが必要だと思う理由

4/23に開催されたGo Conference 2022 Springで 「型パラメータが使えるようになったのでLINQを実装してみた」という発表をしました。
...

http://makiuchi-d.github.io/2022/05/04/gocon-2022-spring.ja.html
Ruby言語 (ruby/ruby) のビルド時に、`make miniruby`がこけた


## エラー詳細

以下どドキュメントに従い、ビルドしようとした。

https://docs.ruby-lang.org/en/master/contributing/building_ruby_md.html

ディレクトリ構成は以下。Rubyのコミットバージョンは、[e1683b4](https://github.com/ruby/ruby/commit/e1683b4958b217d246ff737bdd1b046554c73e18)

```
- workdir
   - ruby
      - build
```

`workdir/ruby/build` 配下で、以下を叩いた。

$ `make miniruby V=1`

```sh
file2lastrev.rb: Command failed with exit 128: git
	BASERUBY = /Users/daiki-kudo/.rbenv/shims/ruby --disable=gems
	CC = clang
	LD = ld
	LDSHARED = clang -dynamiclib
	CFLAGS = -fdeclspec -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wextra-tokens -Wdeprecated-declarations -Wdivision-by-zero -Wdiv-by-zero -Wimplicit-function-declaration -Wimplicit-int -Wmisleading-indentation -Wpointer-arith -Wshorten-64-to-32 -Wwrite-strings -Wold-style-definition -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wunused-variable -Wundef   -pipe 
	XCFLAGS = -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fstack-protector-strong -fno-strict-overflow -fvisibility=hidden -fexcess-precision=standard -DRUBY_EXPORT -fPIE -I. -I.ext/include/x86_64-darwin22 -I../include -I.. -I../enc/unicode/15.0.0 
	CPPFLAGS = -I/usr/local/opt/llvm/include -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT   
	DLDFLAGS = -L/usr/local/opt/llvm/lib -Wl,-multiply_defined,suppress -Wl,-undefined,dynamic_lookup -fstack-protector-strong -Wl,-pie -framework CoreFoundation  
	SOLIBS = -ldl -lobjc -lpthread 
	LANG = 
	LC_ALL = 
	LC_CTYPE = UTF-8
	MFLAGS = 
	RUSTC = rustc
	YJIT_RUSTC_ARGS = --crate-name=yjit --crate-type=staticlib --edition=2021 -g -C lto=thin -C opt-level=3 -C overflow-checks=on '--out-dir=/Users/daiki-kudo/repos/ruby/ruby/build/yjit/target/release/' ../yjit/src/lib.rs
Homebrew clang version 16.0.6
Target: x86_64-apple-darwin22.1.0
Thread model: posix
InstalledDir: /usr/local/opt/llvm/bin
/Users/daiki-kudo/.rbenv/shims/ruby --disable=gems ../tool/file2lastrev.rb -q --revision.h --srcdir=".." --output=revision.h --timestamp=.revision.time
file2lastrev.rb: git rev-parse failed
  fatal: failed to expand user dir in: '~/.gitignore'
make: *** [.revision.time] Error 1
```

## (短期的)解決方法

`workdir/ruby/tool/lib/vcs.rb`を以下のように書き換えた。

```diff
diff --git a/tool/lib/vcs.rb b/tool/lib/vcs.rb
index 8566d72349..0436c0665e 100644
--- a/tool/lib/vcs.rb
+++ b/tool/lib/vcs.rb
@@ -451,7 +451,9 @@ def cmd_pipe_at(srcdir, cmds, &block)
     end
 
     def cmd_read_at(srcdir, cmds)
-      result = without_gitconfig { IO.pread(*cmd_args(cmds, srcdir)) }
+      # result = without_gitconfig { IO.pread(*cmd_args(cmds, srcdir)) }
+      result = IO.pread(*cmd_args(cmds, srcdir))
+
       VCS.dump(result, "result: ") if debug?
       result
     end
```
Flutter pod install エラー 2

# Exception: Error running pod install
> [!] Unable to find a target named `RunnerTests` in project `Runner.xcodeproj`, did find `Runner`.

iOSビルド時のエラー。RunnerTestsがないと言われているが作ったつもりもないのでそりゃないだろうという話

# 対応
``` file:Podfile
target 'Runner' do
  use_frameworks!
  use_modular_headers!

  flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__))
# コメントアウト
#   target 'RunnerTests' do 
#     inherit! :search_paths
#   end
end
```

# なぜ発生したか
おそらくflutterバージョンアップデートに伴い、上記RunnerTests プロファイルがデフォルトで必要になったようだ。古いバージョンで作成したプロジェクトをそのまま引き継ぐ場合、RunnerTests を作成するか、削除するかを行う必要がある。

# その他
[Flutter pod install エラー ハマりどころ](https://qiita.com/hiwazero/items/e9a4aa70be9d23d173bf)
Githubリポジトリに既存プロジェクトを後から追加する7つのステップ

どうもこんにちは、たくびー(＠takubii)です。

Githubでリポジトリを作成する際、通常はリポジトリを作成しクローン後にプロジェクトを作ると思います。私がそうでした。
今回、私はプロジェクトが先にある状態でリポジトリを後から作るという手順でGithubにリポジトリを作成しました。
その手順を共有しようと思います。

### Githubに既にあるプロジェクトを追加する方法

1. まずはコマンドラインでプロジェクトのフォルダへ移動します。ここでは`~/repos/my_project`というフォルダがあることとします。

    ```zsh:terminal
    cd ~/repos/my_project
    ```

2. 次にそのフォルダでGitリポジトリの初期化を行います。

    ```zsh:terminal
    git init
    ```
    ※すでに`.git/`フォルダがある場合は削除しておいてください。

3. Gitリポジトリの初期化が完了したら、すべてのファイルをリポジトリに追加します。

    ```zsh:terminal
    git add .
    ```

4. その後、コミットをします。

    ```zsh:terminal
    git commit -m "First Commit!"
    ```

5. Githubで新しくリポジトリを作成します。作成が完了したらURLをコピーしてください。

6. ローカルのリポジトリにGithubのリポジトリのURLを追加します。

    ```zsh:terminal
    git remote add origin https://github.com/{username}/{new_repo}.git
    ```
    `{username}`、`{new_repo}`の部分は適宜変更してください。

7. 最後にローカルのGitリポジトリの内容をGithubリポジトリにプッシュします。

    ```zsh:terminal
    git push -u origin main
    ```

以上の手順で既存のプロジェクトを後からGithubリポジトリに登録することができます。

なお、特定のファイルやフォルダをGitの追跡対象から除外したい場合は`.gitignore`ファイルに追記してください。

### 終わりに

最初は手元で試していてうまくいったからGithubにあげたいといった時や、ダウンロードしたプロジェクトをGithubで管理したいといった場面で後からGithubに追加したいと思うことが多々ありました。

今まではリポジトリを作成し、そこにコピーしたり、作り直したりといった手間が発生していましたが、上記の手順でスムーズにGithubで管理することができるようになりました。

それでは今回はこのあたりで締めたいと思います。
ここまで読んでいただきありがとうございます。
また機会があればお会いしましょう。
【Unity】プラットフォームごとに処理をわける

### UnityでOSごとに処理内容をわけるには？
UnityでOSごとに処理を分けたい場合に、どのようにコーディングするのかの一例が判明しましたので備忘録として残しておきます。

例)
- 動作環境がAndroidのときはコンソールに`Hello Android.`
- iOSのとはコンソールに`Hello iOS`を出力。
- すべて同じメソッド上で実装。

```csharp:SwitchRunEnv.cs
    void Start()
    {
#if UNITY_ANDROID //Androidの場合の処理
        Debug.Log("Hello Android");
#endif

#if UNITY_IOS //iOSの場合の処理
        Debug.Log("Hello iOS");
#endif
    }
```

### 説明
- `#if`で指定した条件に一致する処理は、`#endif`までが実行されます。
- `#if`や`#endif`は**プリプロセッサディレクティブ**と呼ばれています。
- プリプロセッサディレクティブは他にも`#elif`や`#region`などがあります。気になる方は下記のリンクを参考に
    - [プリプロセッサディレクティブについて](https://learn.microsoft.com/ja-jp/dotnet/csharp/language-reference/preprocessor-directives)
【SwiftUI】キーボードショートカットでボタンアクションを実行する

# はじめに
macアプリでボタンにキーボードショートカットをつける機会があったので方法を記録しておきます。

# 実装
以下の実装の場合は`Command` + `q`でボタンのアクションが実行されます。
```diff_swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        Button {
            exit(0)
        } label: {
            Text("強制終了")
        }
+       .keyboardShortcut("q")
    }
}
```

# おわり
便利なのでキーボードショートカットは実装しておきたいです
OpenWrt ファイアウォール

# はじめに
::: note
### 初心者対応構成
- スクリプトでの自動設定
- UCIとLuCi及びWinSCPにて比較しながら作業がおススメ
:::

::: note
### [PowerShell](https://learn.microsoft.com/ja-jp/powershell/scripting/what-is-windows-powershell?view=powershell-7.4)で[SSHアクセス](https://openwrt.org/docs/guide-quick-start/sshadministration)

- [PowerShellの開始](https://learn.microsoft.com/ja-jp/powershell/scripting/windows-powershell/starting-windows-powershell?view=powershell-7.4) (キー入力)：`Win`+`x` > `a` > `はい`
※Windows7以降標準搭載

```sh
ssh root@192.168.1.1
```

<details><summary>ssh root@192.168.1.1のショートカット作成（デスクトップ）</summary>

```powershell:powershell
$DESKTOP = ([Environment]::GetFolderPath("Desktop") + "\192.168.1.1.lnk")
$WshShell = New-Object -comObject WScript.Shell
$Shortcut = $WshShell.CreateShortcut("$DESKTOP")
$Shortcut.TargetPath = "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"
$Shortcut.Arguments = '-windowstyle hidden -ExecutionPolicy RemoteSigned "Start-Process ssh root@192.168.1.1"'
$Shortcut.IconLocation = "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe,0"
$Shortcut.WorkingDirectory = "."
$Shortcut.Save()

```

- `強制的に貼り付け`
- `yes`

---

</details>

<details><summary>SSHログイン出来ない場合:exclamation:</summary>

known_hostsクリア
- `C:\Users\yourusername\.ssh\known_hosts` ※Windows隠しファイル
```powershell:powershell
Clear-Content .ssh\known_hosts -Force

```
---
OpenSSHのインストール
※Windows 10 Fall Creators Update(1709)以降標準搭載
- 機能の確認
```powershell:powershell
Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH*'

```
- 機能のインストール
```powershell:powershell
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0

```
---

</details>

:::

# ファイアウォール
::: note
### 初期値復元
- [/etc/config/firewall ファイルをゴミ箱に捨ててしまいました。リセットするにはどうすればよいですか?](https://openwrt.org/docs/guide-user/installation/after.installation#i_trashed_myetcconfigfirewall_file_how_to_reset)
```bash
cp -f /rom/etc/config/firewall /etc/config/firewall
/etc/init.d/firewall restart

```
:::
VScodeがDownloadフォルダにあるのにアップデートできない現象の解決法


調べて出てくるのは大体`Visual Studio Code.app`が Download フォルダにないから、という理由ですが、ちゃんと Application フォルダにあったのにエラーが出ていたので解決法を探した。

## エラー全文

```:error
Cannot update while running on a read-only volume.
The application is on a read-only volume.
Please move the application and try again.
If you're on macOS Sierra or later,
you'll need to move the application out of the Downloads directory.
This might mean the application was put on quarantine by macOS.
See this link for more information.
```

## 解決法

エラー文にある [link](https://github.com/microsoft/vscode/issues/7426#issuecomment-425093469) 先のコマンドで解決。
ターミナル(iTerm)で以下のコマンドを実行し、VScode を再起動するとアップデートが問題なく行えました。

```:zsh
xattr -dr com.apple.quarantine /Applications/Visual\ Studio\ Code.app
```

`Visual\ Studio\ Code.app`の部分は自身の VScode の Application 名に合わせてください。
また、iTerm だと実行時パーミッションエラーが出たので、

システム設定 > プライバシーとセキュリティ > アプリケーション管理

で iTerm に権限を付与すると実行できました。

### おわりに

今回、Qiita CLI を使用して記事を書きましたが思ったより使いやすいのでおすすめです。
https://github.com/increments/qiita-cli
Docker Compose+Pythonで環境構築してみる

# はじめに

今回はDocker Composeを使ってPythonの環境を作っていきたいと思います。  
Dockerのインストールは完了していることを前提に進めていきます。

# 環境

DockerとDocker Composeのバージョンは以下の通りです。

```
Docker version 20.10.22, build 3a2c30b63a
Docker Compose version 2.20.3
```

# Dockerの設定
Dockerを使うことによってローカルやリモートマシン上での環境構築を簡単に自動化することができます。

## ファイル構成
まず、以下のようなファイル構成を作っていきます。
```
docker_python
├── Dockerfile
├── app
│   └── sample.py
└── docker-compose.yml
```

## Dockerfile
Dockerは、Dockerfileを読み込むことで自動的にDocker Imageを作成します。  
Dockerfileは、ユーザーがDocker Imageを作成するために必要なコマンドを記載したテキストファイルです。

Dockerfileは次のように記述していきます。
```docker
FROM python:3.9

WORKDIR /app

COPY . .
```

- FROM python:3.9
  - ベースとなるイメージを指定しており、Dockerfileは*FROM*の命令から始めなければならないというルールがあります。
- WORKDIR /app
  - 作業ディレクトリの指定しています。作業ディレクトリを指定することで、その後のRUN, CMD, ENTRYPOINT, COPY, ADDなどの命令がそのディレクトリで実行されます。
- COPY . .
  - ファイルやディレクトリをコンテナのイメージにコピーしています。  
  - 最初の `.` はビルドコンテキスト(通常はDockerfileがあるディレクトリ)の中の全てのファイルとディレクトリを指します。  
  - 2番目の `.` はコンテナ内の作業ディレクトリを指します。この作業ディレクトリは、WORKDIR命令で指定されたディレクトリです。もしWORKDIRが設定されていなければ、ルートディレクトリを指します。

## docker-compose.yml
docker-compose.ymlは複数のDockerコンテナを一緒に定義・実行するための設定ファイルです。  
YAML形式で記述され、各サービスを個別に定義します。

```yml
version: "3"
services:
  docker_python:
    container_name: python
    build:
      context: .
      dockerfile: Dockerfile
    working_dir: "/app/"
    tty: true
    volumes:
      - .:/app
```

- version: 
  - 使用するdocker-composeファイルフォーマットのバージョンを指定します。
- build: 
  - Dockerfileのあるディレクトリやビルドの指定します。
  - context: .
    - ビルドコンテキストを指定します。. はカレントディレクトリを意味します。
  - dockerfile： Dockerfile
    - イメージのビルドに使用するDockerfileの名前を指定します。この場合、カレントディレクトリにあるDockerfileという名前のファイルを指します。
- working_dir: "/app/"
    - コンテナ内の作業ディレクトリを/app/に設定する。
- tty: true
  - 擬似TTYを割り当てるもので、ターミナルでコンテナとやり取りしたい場合に便利です。
- .:/app
  - ホストのカレントディレクトリをコンテナ内の /app にマッピングします。これによって開発時にホストのappディレクトリで行った変更が即座にコンテナ内に反映されます。


## sample.py
動作を確認するため、sample.pyには以下の一行を記載しておきます。
```python3
print("Hello World!")
```

# Dockerのコンテナのビルドと起動
以下のコマンドでコンテナの作成と起動を行います。
```bash
cd docker_python
docker compose up -d --build
```

# コンテナへの接続とHello World!の出力
まず、コンテナに接続します。
```bash
docker exec -it python bash
```

コンテナに接続した状態で以下を実行すると
```bash
root@57ce8b6f9197:/app# python3 app/sample.py
```

Hello Worldが出力されます。
これで、DockerとPythonで環境構築することができました。
```bash
Hello World!
```

# おわりに
今回はdocker-composeとPythonで環境構築を行ってみました。  
Dockerは非常に便利などで今後も積極的に使っていきたいと思います。

以上です。お疲れ様でした。
システムの性能

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457284/f95f9a49-f8ce-3c9c-0c19-2aec0b4d4189.png)
　システムの性能を数値で表すと、性能の評価がしやすくなります。CPUの性能を表す指標にはMIPSやFLOPSがあります。しかし、システム全体の性能だけで決まるわけではありません。メモリやハードディスク装置、ネットワークの性能も盈虚します。これらを総合してシステム全体の性能を表すには、スループットやレスポンスタイムといった指標を用います。

１：MIPS（Million Instructions Per Second）は、１秒間に実行できる命令数をヒョクマン単位で表す指標です。

２：命令ミックス
　１命令の実行時間は命令ごとに異なります。そこで、１命令あたりの平均実行時間を求めて、その値からMIPS値を計算します。命令ミックスは、一般的なプログラムにおける命令の出現頻度を定めたもので、１命令あたりの平均実行時間を求めるために利用できます。

３：FLOPS（FLOating point Operations Per Second）は、１秒間に実行できる浮動小数点演算の回数を表す指標です。スーパコンピュータに代表される科学技術計算（シュミレーションや数値解析）を主として行うコンピュータの性能を表すために使います。また、パソコンのグラフィックカードも、３D画像を描くために多くの不動小数点演算を行います。金連では、グラフィックカードの性能もFLOPSで表すことが多いです。

４：スループット
　単位時間（1秒、1分など）にコンピュータが処理できる仕事の量を表す指標です。１秒間に処理できる要求の数（要求/秒）や、１秒間に処理できるトランザクションの数（トランザクション/秒、TPS）などで表す。

試験の出題例：スループットとは、「コンピュータすしテムによって単位時間あたりに処理される仕事量」

５：スプーリング、バッファリング
　スプーリングとは、ハードディスクなどの比較的高速な補助記憶装置を介して、プリンタなどの低速出力装置へ出力する仕組みです。例えば、ワープロソフトからプリンタへ出力する場合、出力データを直接プリンタに送ったのでは、プリンタが印刷し終えるまでの間、ワープロソフトが待つことになり、ワープロソフト上で別の作業をすることができなくなります。

　スプーリングを利用すると、ワープロソフトは、いったん、出力データをスプーラという気候に渡します。スプーラは、出力データをどんどん受け取って、とりあえず、ハードディスクなどの補助記憶装置に書き出しておきます。ハードディスク装置などの補助記憶装置は、プリンタに比べれば高速に動作しますかr、あスプーラは、短時間でたくさんのデータを受け取れます。結果的に、ワープロソフトは、すべての出力データを短時間でスプーラに渡し、自身は、印刷を完了したという状態でできます。従って、その後、別の作業をすることができるようになります。一方で、スプーラは圃場記憶装置に格納したデータを、プリンタに順次送っていきます。

　この結果、プリンタで印刷しながら、ワープロソフトで別の作業を行うことができるようになり、スループットが向上するのです。このような動作は、現在のパソコンでは当然のようにできているわけですが、スプーリングという仕組みが備わっているからこそ可能なのです。

　スプーリング（スプール）に似た用語にバッファリング（バッファ）があります。スプーリングもバッファリングもスループットを向上させることが目的の技術です。

　プロセス（プログラム）が出力するデータに着目して、プロセスのスループットを向上させるということを考える場合には、スプーリングということが多いです。

　一方で、入出力装置（ハードディスク装置やSSDなど）と処理装置（CPU）に着目して、処理速度の差を緩和することで、処理装置のスループットを向上させるという場合にはバッファリングということが多いです。バッファリングでは、入出力装置へ書き込むデータをバッファメモリというメモリ（もしくは、バッファ領域の一部）に一旦書き出しておき、書き込むデータがある程度たまってきたところで、まとめておき、バッファメモリへ貯めておきます。処理装置からの要求に応じて、必要な分だけバッファメモリから読み出し、処理装置へ送ります。

６：レスポンスタイムとターンアラウンドタイム
　レスポンスタイム（応答時間）は、コンピュータに処理の指示を出してから、結果の表示が始まるまでにかかる時間です。主にオンライントランザクション処理システム、クライアントサーバシステム、リアルタイム処理システムの性能を表す用途で使われます。

　一方、ターンアラウンドタイムは、入力を開始してから結果の出力が完了するまでにかかる時間です。コンピュータセンタまでデータを送る時間や、コンピュータセンタから出力結果が届くまでの時間も含んでいます。例えば、データをDVDに書き込んで郵送でコンピュータセンタに送るとすると、郵送にかかる時間まで含んで、ターンアラウンドタイムと言います。ターンアラウンドタイムには、コンピュータシステムの性能とは無関係の要素も含まれるのです。ターンアラウンドタイムは、主にバッチ処理システムの性能を表す用途で使われます。

７：スケールアップとスケールアウト
　CPUを高速なものに置き換えたり、メモリを増設したりして、サーバ機（ホストコンピュータ）単体の性能を向上させてシステム全体の性能を高めることをスケールアップと言います。一方で、サーバ機（ホストコンピュータ）の台数を増やしてシステム全体の性能を高めることをスケールアウトと言います。

８：ベンチマークテスト
　性能評価用のプログラムを用意して、それを実行した時の結果（所要時間など）によって、性能を相対評価する手法をベンチマーークテスト手法と言います。主なベンチマークテストには、プロセッサの演算性能を評価するSPECや、トランザクション処理性能を評価するTPCがあります。

試験の出題例：ベンチマークテストでは、「測定用のソフトウェアを実行し、システムの処理性能を数値化」
コメントのsummaryって何？

# コード中に度々目にする例のアレの正体
他人が開発したコードを読んでいると、時々メソッド（関数）の前などにコメントとして下のような記述をみたことがありませんか。
```c#:C#
/// <summary>
///  （メソッドの説明が書かれている）
/// </summary>
void ShowCommet()
{
    Debug.Log("Comment");
}

```
このメソッド直前にある`<summary>`と`</summary>`のコメントは**document comment（ドキュメントコメント**と呼ばれています。

## ドキュメントコメントとは？
ドキュメントコメントは、その名の通り、ドキュメント生成用のコメントです。プログラムの説明用に残せるコメントでもあり、設定によってはドキュメントコメントをもとにXML形式で出力できます。（この記事ではxml形式で出力する方法は割愛しています）
また、visual studio上で、ドキュメントコメントが併記されているメソッドにマウスカーソルを合わせると、下図のように説明が表示されることも特徴です。
```C#:サンプル用メソッド
/// <summary>
///  テスト用メソッド。コンソールに出力します。
/// </summary>
void ShowComment()
{
    Debug.Log("hello world!");
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524447/82cc8b1d-d7e2-653a-f427-74a3e8b328ee.png)
- **ドキュメントコメントは形式化されている**ため、例えば上の`<summary>`の直前は`///`のようにスラッシュが３本ですが、これが２本のスラッシュ`//`だとドキュメントコメントとはならず、メソッドにマウスカーソルを合わせても何も表示されません。
先ほどのコメントで実際に`<summary>`の直前を`//`で指定したときの表示が下図になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524447/1c50a74d-1fe1-d51c-4838-79ed290c35fb.png)
- はじめてソースコードを見た人に理解の助けとなるような説明を残せることができますので可読性の向上につながります。
- 他にも、関数の引数や返り値の説明もドキュメントコメントとして残せます。引数として指定したnum1、num2にマウスカーソルを合わせると下図のように表示してくれます。
```C#:サンプル用メソッド
    /// <summary>
    ///  テスト用メソッド
    /// </summary>
    /// <param name="num1">コンソールで１つ目に表示させたい数値が引数num1です。</param>
    /// <param name="num2">コンソールで２つ目に表示させたい数値が引数num2です。</param>
    /// <returns>引数で受け取った値の合計値を返す</returns>
    int ShowComment(int num1, int num2)
    {
        Debug.Log("num1:"+ num1);
        Debug.Log("num2:"+ num2);
        return num1 + num2;
    }
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524447/41771a4b-9e04-c592-39f9-40924f95b389.png)


## ドキュメントコメントの種類
ドキュメントコメントは上記で紹介したメソッドの説明用だけじゃなくても他にも様々な形式が存在します。（ちなみに、自分は全く覚えてません。）

参考として公式サイトのリンクを張っておきます
[C#版ドキュメントコメントの説明　Microsoft公式サイト](https://learn.microsoft.com/ja-jp/dotnet/visual-basic/reference/language-specification/documentation-comments)

## まとめ
- ドキュメントコメントは形式が定められている
- ドキュメントコメントはプログラムの説明用に残せる、ドキュメント生成用のコメント
ラズパイにNeovimをインストールしてプラグインを入れるまで(64bit)

::: note warn
注意
64bit版のRaspberry Pi OS向けの記事です。
32bit版（通常版）については検証中ですのでご注意ください。
:::

# Neovim をインストール
ラズパイ標準のaptではnvimのバージョンが0.4.4-1となっており、かなり古いです。
(現時点での最新バージョンは0.9.1)

ですので、snapパッケージを利用して最新のnvimをインストールします。

``` bash
sudo apt install snapd
sudo snap install --classic nvim
```

### パスを追加

``` ~/.bashrc
#末尾に追記
PATH=/snap/bin:$PATH
```

vimで起動したい場合は```alias vim=nvim```も追記してください。

参考

https://raspberrypi.stackexchange.com/questions/118881/how-to-install-the-latest-version-of-neovim

# vim-plug をインストール

ここではvim-plugのインストール方法を説明します。
設定がシンプルなので個人的におすすめです。

https://github.com/junegunn/vim-plug

``` bash
sh -c 'curl -fLo ~/.local/share/nvim/site/autoload/plug.vim --create-dirs https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim'
```

設定は`~/.config/nvim/init.vim`に書きます。
``` bash
mkdir -p ~/.config/nvim
vim ~/.config/nvim/init.vim
```

例
``` ~/.config/nvim/init.vim
set number

" ↓ プラグインの記述はこの中に書く
call plug#begin()

" githubで公開されているプラグインは 作者名/リポジトリ名 で指定できる
Plug 'neoclide/coc.nvim', {'branch': 'release'}

call plug#end()
```

`init.vim`の書き方の詳細はこちら


https://github.com/junegunn/vim-plug#example


ちなみに`~/.vimrc`は認識されませんでした。

# coc.nvim をインストール

coc.nvimはインストールするだけでnvimをvscodeのように拡張するプラグインです。

https://github.com/neoclide/coc.nvim

インストール方法は他のプラグインと同じですが、coc.nvimは入力補完などの機能を実現するために **nodejs** を利用しているので、そちらのインストールも必要となります。

### nodejs をインストール

64bitのラズパイ (aarch64)に対応したnodejsをインストールするため、Nodesourceを利用します。（公式です）

https://github.com/nodesource/distributions#debinstall

LTSのバージョンをインストールします。
``` bash
curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -

# 他のバージョンもインストールできます
#curl -fsSL https://deb.nodesource.com/setup_21.x | sudo -E bash -
#curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
#curl -fsSL https://deb.nodesource.com/setup_19.x | sudo -E bash -


sudo apt install nodejs
```
``` bash
$ node --version
v19.9.0
```

### coc.nvim をインストール

`~/.config/nvim/init.vim` に記入します。

``` ~/.config/nvim/init.vim
 ...
call plug#begin()

 ...

" ↓ 追記
Plug 'neoclide/coc.nvim', {'branch': 'release'}

 ...

call plug#end()
```

vimを再起動し、`:PlugInstall`を実行すると、インストールされます。

また、実際にcoc.nvimで入力補完などの機能を利用するには、それに対応した言語サーバーを追加する必要があります。
例） HTML → `:CocInstall coc-html`を実行して追加

↓こちらに一覧があります

https://github.com/neoclide/coc.nvim/wiki/Language-servers
プログラミング開発で手戻りを減らす心構えは

手戻りを減らす心構えは

- 必要なコミュニケーションは厭わない (お客さんやチームと)
- 要件確定前に作り込みすぎない
- 未来を予測する (確率の大きな方に賭ける)

だが時と場合によってはどうしても手戻りを起こしてしまう。

例えば

- 要件確定前に先行して機能開発をしてした
- 要件確定・仕様変更でDB設計が大きく変わった
- ブランチを分けて管理することになり大幅にコードを変えた
- ブランチを分けた後に大幅なリファクタリングをしてコンフリクト解消に時間がかかった
- 最初から命名に迷っていた部分があったが後から名前を変えることになった

穴を掘ってはそれを埋めているような気分になる。
まずい設計やまずい命名をすればそれがいつまでも気になるが逆に事前の設計や事後のリファクタリングにこだわりすぎるとそれはそれで無駄なこだわりのために途方もなく時間を費やしているような気持ちになる。

手を動かし続けていれば常に何らかの個人的な達成感はあるかもしれないがそれはプロジェクトの進捗度合いとは必ずしも関係ない。
「動けば良い」と「良い設計」の間を行き来し続けるのだ。



# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# Twitter

https://twitter.com/YumaInaura
【React】selected属性を使わずにvalue属性を使う

Reactでselectタグのselected属性を用いて初期選択状態を作ろうとするとエラーが発生する。
```React
<select>
    <option value="apple">Apple</option>
    <option value="banana" selected>Banana</option>
    <option value="grape">Grape</option>    
</select>
// Warning: Use the `defaultValue` or `value` props on <select> instead of setting `selected` on <option>.
```


上記のエラーを読み取ると、どうやらReactでselectの初期選択状態を実装したい場合は、selected属性ではなくdefaultValue属性かvalue属性を使用しないといけないとのこと。
（[React公式ドキュメント](https://ja.legacy.reactjs.org/docs/forms.html#the-select-tag "React公式ドキュメント")にも書かれていました。）


以下のようにvalue属性を用いて実装するとエラーを解消できる。
```React
<select value={ optionState } onChange={ (e)=>setOptionState(e.target.value) }>
    <option value="apple">Apple</option>
    <option value="banana">Banana</option>
    <option value="grape">Grape</option>
</select>
```
selectタグのvalue属性で指定した値と一致するoptionタグが初期選択状態になる。
また、value属性にステートを用いる場合は、onChangeでステート更新する必要がある。
【trocco】カスタム変数に指定できる値の優先順位

## 背景
troccoには転送設定やデータマート定義でカスタム変数が使えます。

カスタム変数の用途は例えば、
- SQLに実行時の日付を含めたい
- あるテーブルのカラムの日付でループさせたい
などSQLだけでは難しい処理を実現するために使えます。

そのカスタム変数に値を指定できる場所は複数あります

指定方法1. 転送設定/データマート定義内での指定
![データマート定義の編集___trocco.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341549/62ab439d-8e11-9fe2-0989-5efbf4cb2e43.png)

指定方法2. 転送設定/データマート定義の実行時の指定
![新規シンクジョブの実行___trocco.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341549/78dc721d-4fc6-3e5f-aea7-97f8f07aa977.png)


指定方法3. ワークフロー設定時のループの指定
![ワークフロー定義編集___trocco.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341549/ef2a8366-7440-0232-0121-a76c3e5ac6d2.png)


指定方法4. ワークフロー実行時の指定
![ワークフロー詳細___trocco.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/341549/f09cd98c-a509-acea-a311-b3587d469eb6.png)


これらを同時に指定したときにどの指定が優先されるのかがドキュメントからはわからなかったため実行して試してみました。

## 結論
今回は上記の指定方法1, 3, 4を同時に試してみたところ、優先度は以下の順番で高かったです（上が優先される）。

指定方法3. ワークフロー設定時のループの指定 ※ワークフローが入れ子になっている場合、内側の指定の方が優先されます
指定方法4. ワークフロー実行時の指定
指定方法1. 転送設定/データマート定義内での指定
Nuxtにてnpm link {パッケージ}で開発中のローカルパッケージへのシンボリックリンクを張るとnpm run devでFailed to load urlエラーになる

nuxt.config.tsでviteの設定を変更する必要がある

```nuxt.config.ts
  ・・・
  vite: {
    resolve: {
      preserveSymlinks: true,
    },
```

# 環境

- Ubuntu in WSL2
- Nuxt 3.6.5


### 参考
- https://github.com/nuxt/nuxt/issues/22278#issuecomment-1648553586
- https://ja.vitejs.dev/config/shared-options.html#resolve-preservesymlinks
Node.jsのインストールとVsCodeでの設定


### はじめに

この記事では、Node.jsのインストール手順と、VsCodeで使用できなかった場合の対処法について説明します。Node.jsはJavaScriptのランタイム環境であり、Webアプリケーションの開発などに広く利用されています。

### Node.jsのインストール手順

1. **公式ウェブサイトからダウンロード**: [Node.jsの公式ウェブサイト](https://nodejs.org/) にアクセスして、最新バージョンのNode.jsをダウンロードします。

2. **インストーラーを実行**: ダウンロードしたインストーラーを実行し、指示に従ってインストールを進めます。インストール中に設定を変更する必要があれば適宜行ってください。

3. **環境変数の設定**: インストールが完了したら、環境変数にNode.jsの実行パスを追加します。以下の手順で設定できます。

   - [Windowsの場合] PowerShellを開いて以下のコマンドを実行します。
     ```powershell
     [Environment]::SetEnvironmentVariable("Path", $env:Path + ";C:\Program Files\nodejs", "Machine")
     ```
   - [macOSの場合] ターミナルを開いて以下のコマンドを実行します。
     ```bash
     echo 'export PATH="/usr/local/bin:$PATH"' >> ~/.bash_profile
     source ~/.bash_profile
     ```
   - [Linuxの場合] ターミナルを開いて以下のコマンドを実行します（ディストリビューションによってコマンドが異なる場合があります）。
     ```bash
     sudo apt-get update
     sudo apt-get install nodejs npm
     ```

### VsCodeでの設定

#### 1. VsCodeでNode.js拡張機能をインストール

VsCodeの拡張機能マーケットプレイスから、Node.jsに関する拡張機能をインストールします。

#### 2. VsCodeのターミナルでNode.jsコマンドを実行できるか確認

1. VsCodeを開いて、左下にあるターミナルアイコン（ターミナルパネル）をクリックします。

2. ターミナルが開いたら、以下のコマンドを入力してNode.jsが正しくインストールされているか確認します。
   ```bash
   node -v
   npm -v
   ```

#### 3. インストール時の注意点

- インストール後にコンピューターを再起動することで、環境変数の変更が正しく反映される場合があります。
- インストールディレクトリが正しく指定されているか確認してください。特にWindowsの場合は、インストール先が正しいパスになっているか注意が必要です。

### おわりに

以上でNode.jsのインストールとVsCodeでの設定が完了します。インストールや設定で問題が発生した場合は、公式ドキュメントやエラーメッセージを参考に解決方法を探してみてください。
Nuxt3 – useFetch で 固定の key を指定してもほとんどキャッシュしてくれない件

# 環境

Nuxt 3.6.5

# NOTE

SSRまたは非SSR

`ssr: true`
`ssr: false`

DEVモードもしくはPRODUCTION モード

dev / start

それぞれ動作を確認したが「ほとんどの場合」でキャッシュしてくれなかった

# 例1 – script 直下で fetch

- SSRだと複数回リクエストされる(キャッシュが効いていない)
- 非SSRだと1回だけリクエストされる(キャッシュが効いている)

```vue
<script setup lang="ts">
await useFetch("https://example.com", { key: "XXX" })
await useFetch("https://example.com", { key: "XXX" })
await useFetch("https://example.com", { key: "XXX" })
</script>
```

await を外すとどちらのモードでもキャッシュは効かなかった

# 例2 – ボタンを押して fetch する場合

```vue
<script setup lang="ts">
const result = ref([])
async function click() {
  const { data } = await useFetch("https://httpbin.org/get", {
    key: "XXX",
  })
  result.value = data
}
</script>

<template>
  <div>
    <button @click="click">click</button>
  </div>
  {{ result }}
</template>
```

SSRでも非SSRでもボタンを押すたびにリクエストされる (キャッシュが効いていない)


# DevTool

nuxt dev tool  ではまるでキャッシュが効いて1回しかリクエストがおこなわれていないかの用に見えるが、実際にリクエストを受ける側のサーバーでアクセスログを確認するとそうではないことが分かった。
単に DevTool  ( `v0.3.1 (experimental)` )の仕様で同じキーは表示がまとめられてしまうとかいう挙動になっているかもしれない。

<img width="657" alt="image" src="https://github.com/YumaInaura/YumaInaura/assets/13635059/fec66bcb-1239-454f-91a2-24fae1ab5d3d">


# 経緯

useFetch で key 指定をしないと 同じURLに対して 複数回リクエストが発行されない (キャッシュが効いてしまう) という問題を調べていた。

だがいざ試してみると何故かほとんどの場合でキャッシュを効かせることの方が難しかった。
( 古いバージョンで 3.0.0 stable の動きを試したりもしたのだが )

# 関連

>未検証ですが、おそらく key には ファイルと行数が自動で使われる という挙動になっていると思われます。

https://zenn.dev/ytr0903/articles/6acccb5fa816ee

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89618/be47fe45-59ed-999a-b006-c9e79e53ec5a.png)

https://techblog.sakurug.co.jp/article/nuxt3rc-usefetch/

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# Twitter

https://twitter.com/YumaInaura
[JSTQB AL TA]　4.ソフトウェア品質特性のテスト　を視覚的にまとめてみた

# はじめに

こんにちは、Ma5am1nです。
[シラバス](https://jstqb.jp/dl/jstqb.jpdlJSTQB-SyllabusALTA_V311.J03.pdf)[^1]は文字が多くて頭に入りにくいので、図など視覚的に入ってきやすそうな形式でまとめてみます。

[^1]: Advanced Level シラバス日本語版　テストアナリスト　Version 3.1.1.J03 

**※あくまで私個人の解釈で作成したものです。内容が100%シラバスの通りであることは保証できませんので、ご了承ください。**
**※スライドの青文字、青線になっている箇所は、シラバスに記載されていない、私独自の解釈で記載した内容です。**

このページでは、4.ソフトウェア品質特性のテスト　について扱います。

# 4.ソフトウェア品質特性のテスト
## 4.1イントロダクション
![JSTQB AL TA-78.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1636570/c4d5c2b7-881f-8750-6ef6-ff20aa981137.png)
![JSTQB AL TA-79.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1636570/c21b3c82-4f9b-2833-ce47-20389ee9d005.png)

## 4.2ビジネスドメインテストの品質特性
![JSTQB AL TA-81.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1636570/8e6f33c3-8fbd-c9a1-a7d7-8434c708d04c.png)

### 4.2.1機能正確性テスト、4.2.2機能適切性テスト
![JSTQB AL TA-83.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1636570/849096e8-08c8-0d44-336d-be7ee2278a0a.png)

### 4.2.3機能完全性テスト
![JSTQB AL TA-85.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1636570/cf8dbee3-cd8e-8727-6014-4e20b710154e.png)

### 4.2.4相互運用性テスト
![JSTQB AL TA-87.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1636570/7ce7fbb7-f89e-53cb-46cc-8c86c49c4457.png)
![JSTQB AL TA-88.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1636570/7cdfd1e4-e5b7-2c28-f610-0bdd0681f56a.png)

### 4.2.5使用性テスト
![JSTQB AL TA-90.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1636570/5ca11d5c-e3f5-5800-5d43-be6d1043c541.png)

#### 4.2.5.1使用性の側面
![JSTQB AL TA-92.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1636570/844d562f-d764-d4df-b1be-d04b85bfc90a.png)
![JSTQB AL TA-93.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1636570/9d5a235f-7b48-4b6e-e4b5-e44ba2bd2322.png)

#### 4.2.5.2使用性評価手法
![JSTQB AL TA-95.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1636570/0086c950-2537-b189-574b-9ddaf57e6269.png)

### 4.2.6移植性テスト
![JSTQB AL TA-97.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1636570/d8cd1920-29e1-7f2f-ea2b-4e2c61139c8d.png)
![JSTQB AL TA-98.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1636570/d4d9907b-f422-2fb6-3c7f-076bf9edf17c.png)
LINE Bot 西暦和暦を相互変換して教えてくれる！

これまでLINEなどのアプリを使う立場だった素人がMakeに関して、少しかじったことで、
LINE BotとMakeを使って西暦和暦を相互に変換してくれるLINEアカウント作成に挑戦した。
![814-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3505389/bf7f850b-f2ec-f3ab-07e3-692f178cde05.png)
仕事柄で西暦のこの年って、和暦で何年でしたっけと、WEB上で検索したりすることがよくあった。またその逆の場合もあった。
WEB検索せず、すぐに教えてくれる何かがあればいいなと常に思っていた。
では、LINE BotとMakeで作ってみよう。

思い立ったら、行動する！
まず、西暦和暦変換用APIの検索から始めた、
しかし、これだ！と思うものがなかった。

API検索で苦労するとの話はきいたことあるが、やってみるとやはりか・・・
とその気持ちがよく分かった。

まず、どのようにすればいいのか、早速調べた。
GooglesheetをAPI化して、JSONデータに変換してくれるサイト「SSSAPI」
の存在を知った。

早速、Googlesheetを作成した。これは簡単！
![シート.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3505389/2379963c-2211-f48a-60cf-c435c44d1abc.png)
そして、「SSSAPI」サイトにシートを読み込んでAPI URLを発行してくれる。
データはこのように変身！
![JSON2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3505389/78cc46fd-a3f3-36ca-88a8-7d6aded5a298.png)
これでMakeにLINEbotを作成し、HTTPをつなげて、
（作成に参考した動画　https://www.youtube.com/watch?v=D3H-bI-qPMI）

![Make画像.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3505389/79df626d-50f4-1cda-4cc6-ece91abec11c.png)
試してみると、これだ！と思いきや、何を入れても同じ答えが返ってくる:sweat:
これでは困る！
どうしたらいい？

APIの利用方法を調べることにした。
フィルタリングが必要のようで、
![814ー２.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3505389/eee7345b-470c-6818-3f51-cdb1822674eb.png)
これで和暦から西暦に変換成功！
また、欲が出てきて、逆のパターンもほしいと、
このようにルーターを入れることで西暦から和暦に変換するほうもいれた。
フィルターの設定で和暦の年号を条件として入れた。
![814.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3505389/2efd8840-3981-958c-34c0-0be8ced354bf.png)
![814-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3505389/b9dbeb8f-b5ca-5c74-4fc8-dc91985d2b98.png)
もちろんすんなりと行くことなく、幾度もエラーを出したこともあったが、
やがて成功にたどり着いた！！！

実際に動かした動画はこちら
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Makeで作成したLineBotで西暦を和暦に変換して教えてくれる動画です。 <a href="https://t.co/6Tpjv6Ndti">pic.twitter.com/6Tpjv6Ndti</a></p>&mdash; トミー (@h21550) <a href="https://twitter.com/h21550/status/1691081128738684929?ref_src=twsrc%5Etfw">August 14, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

使用ツール
・LINE
・Make
・Goolesheet
・SSSAPI

自慢げに家族に見せて、使ってもらったら、すごい！との一言、
素直にうれしい！と思った、達成感満載の一日だった！
rex0220 一括更新プラグイン ユーザー選択の更新

[一括更新プラグイン](https://qiita.com/rex0220/items/f90ca06fde6b6e362583)のユーザー選択項目の更新について、プラグイン設定とユーザー選択項目の入力方法を解説します。

# 概要

kintoneアプリストアの問い合わせ管理アプリを利用します。
ユーザー選択項目の担当者について、一覧から一括更新を行います。

![2023-08-12_19h42_52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/84b021bb-9415-2758-e637-8f582e02ef00.png)

# 操作例
未担当の問合せ一覧からレコードを選択して、自分を対応担当者に割り当て、期限を設定して更新します。

![2023-08-12_19h59_28.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/bed8e8bd-8c03-c05c-e842-b5c93071d192.gif)

# ユーザー選択項目の操作

- 組織・グループ・ユーザーの指定により、ドロップダウンの表示が変わります。
![2023-08-12_20h12_27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/28c8baca-199b-d02a-6161-2256198830ba.png)

- 組織　※ユーザーが複数組織に所属している場合、「優先する組織」にのみ表示されます。
![2023-08-12_20h10_47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/7882a0bd-1dcb-a3a8-0b48-d281970d8435.png)
- グループ　※ユーザーが複数グループに所属している場合、先頭のグループにのみ表示されます。
![2023-08-12_20h11_32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/0520083c-9e16-06c7-ee66-672c02d9368a.png)
- ユーザー
![2023-08-12_20h11_47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/e5c0b346-e365-a2a0-1691-0216b1ad010a.png)

- 文字入力による絞り込み
ユーザー名称またはコードを入力するとユーザーの絞り込みができます。
![2023-08-12_20h15_34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/6d32dc21-0797-2a0b-e939-b459e1a8ca85.png)

- ドラッグアンドドロップで、ユーザー位置を変更
![2023-08-13_09h28_36.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/19db6c8e-db8f-cfc4-bba0-789556b4d9d3.gif)

# プラグイン設定
対応担当者の初期表示に、ログインユーザーを指定します。

- レコード選択をチェック
- ボタン名：　担当設定
![2023-08-12_20h04_20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/f631b95e-274b-d430-abf3-f9fc021c67c9.png)

## 初期表示にログインユーザーを設定
- 項目設定
    - 対応担当者：　入力、有効をチェック
        - 計算式：　LOGIN_CODE()  ※初期表示にログインユーザーを設定
    - 対応状況：　入力をチェック
    - 期限：　入力をチェック
![2023-08-12_20h05_24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/01032649-3666-9ecd-d018-ef7efe8a6ec9.png)

## 初期表示にログインユーザーの組織メンバーを設定
![2023-08-13_09h51_54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/d1512a42-d663-bfb8-1414-197e95bf3ba6.png)

- 対応担当者 計算式：

```.js
UINFO(
  OINFO(
     UINFO(LOGIN_CODE(),"primaryOrganization"),
  "users"),
"code")
```
   
![2023-08-13_09h48_26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/cfc54d2c-2b8e-4157-8d8c-a07fcbac99b7.png)
ReactのuseStateをコンポーネント間で共有して状態を維持する

Reactに少しずつ慣れてきました。

始め立てのうちは1ファイルにザーッとコードを書いて動いたら満足！って感じでしたが、慣れてくると機能ごとにコンポーネント分けしてコード整理したくなってきます。

例えば、以下のようなボタンを押すと表示が切り替わるようなコード。

## コードサンプル

```react:page.tsx
"use client";

import { useState } from "react";

export default function Home() {
  const [open, setOpen] = useState(false);

  const handleClick = () => {
    setOpen(!open);
  };

  return (
    <main className="flex min-h-screen flex-col items-center justify-center p-24">
      <button
        className="bg-slate-700 text-white px-10 py-5"
        onClick={handleClick}
      >
        ボタン
      </button>
      <div className="mt-10">
        {!open ? "ボタンをクリックしてください" : "ボタンをクリックされました"}
      </div>
    </main>
  );
}
```

![2023-08-12_17h22_54.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183668/19dc2564-2305-7feb-a658-a49ea0a7765b.gif)

## propsで状態を渡しコンポーネント分けする

これを親コンポーネントと子コンポーネント（ボタン、テキスト）に分けたくなったとします。

コード内には、状態管理をするための`useState`が存在しています。
状態を管理しているStateが親ファイルと子ファイル間で分かれてしまうとどうなるでしょう。

当然状態は管理できなくなり更新が効かなくなります。

んーどうしましょう？

Reactにはデータを親コンポーネントから子コンポーネントに受け渡しできるpropsという機能がありました。

実はこの**propsは数値や文字列だけではなく、関数や状態まで渡せる**のです！

早速、ボタンとテキストをそれぞれコンポーネント化してみます。

```react:page.tsx
"use client";

import { useState } from "react";

import { Button } from "../components/Button";
import { Text } from "../components/Text";

export default function Home() {
  const [open, setOpen] = useState(false);

  const handleClick = () => {
    setOpen(!open);
  };

  return (
    <main className="flex min-h-screen flex-col items-center justify-center p-24">
      <Button handler={handleClick} />
      <Text isOpen={open} />
    </main>
  );
}
```

`<Button />`にはイベントハンドラーが必要なのでhandlerというpropsでhandleClick関数を渡し、`<Text />`にはisOpenというpropsでStateを渡しています。

props名は自由なので各々変えていただいて大丈夫です。

```react:Button.tsx
export const Button = ({ handler }: { handler: () => void }) => {
  return (
    <>
      <button className="bg-slate-700 text-white px-10 py-5" onClick={handler}>
        ボタン
      </button>
    </>
  );
};
```

Buttonコンポーネントでhandlerを受け取ったので、onClickイベントにhandlerを指定します。

```react:Text.tsx
export const Text = ({ isOpen }: { isOpen: boolean }) => {
  return (
    <div className="mt-10">
      {!isOpen ? "ボタンをクリックしてください" : "ボタンをクリックされました"}
    </div>
  );
};
```

同様にTextコンポーネントでStateを受け取り、三項演算子（条件式）で分岐を作ります。

これで状態を維持したまま、コードを整形することができました！
タイタニック号のデータが入っているパスを取得

Kaggleのコンペの一つ「タイタニック号」のデータが入っているpathの取得方法についてまとめます。


```Python
import os
for dirname, _, filenames in os.walk('/kaggle/input'):
    for filename in filenames:
        print(os.path.join(dirname, filename))
```
1つずつ見ていきましょう。

```Python
import os
```
osモジュールについて下記の記事を読んでみました。
https://www.sejuku.net/blog/67787

以下原文↓
osモジュールは、OSに依存しているさまざまな機能を利用するためのモジュールです。
主にファイルやディレクトリ操作が可能で、ファイルの一覧やpathを取得できたり、新規にファイル・ディレクトリを作成することができます。

続きます。

```Python
for dirname, _, filenames in os.walk('/kaggle/input'):
    for filename in filenames:
        print(os.path.join(dirname, filename))
```
https://docs.python.org/ja/3/library/os.html?highlight=os%20walk#os.walk

os.walk()メソッドは、引数に受け取ったディレクトリツリー以下のファイル名をツリーをトップダウンもしくはボトムアップに走査することで作成します。
デフォルト仕様は下記のとおりです。

```Python
os.walk(top, topdown=True, onerror=None, followlinks=False)
```

ディレクトリツリーを走査した結果、戻り値として、
①ディレクトリ名
②内包するディレクトリリスト
③内包するファイルリスト
が返ってきます。

試しに、/kaggle/input の中身をdirname, names, filenamesとして取り出し、printしてみると、

```Python
for dirname, names, filenames in os.walk('/kaggle/input'):
    print(dirname)
    print(names)
    print(filenames)
```
/kaggle/input
['titanic']
[]
/kaggle/input/titanic
[]
['train.csv', 'test.csv', 'gender_submission.csv']

と返ってきました。

今回は内包するディレクトリリストはtitanicのみで
/kaggle/input/titanic の中に、
['train.csv', 'test.csv', 'gender_submission.csv']
という3つのcsvファイルが入っているディレクトリ構造であることがわかりました。

2つめのfor文では、filenamesに格納された3つのcsvファイルを要素として含むリストから、ファイルを1つずつfilenameという変数に取り出し、
os.path.joinメソッドで、ディレクトリのパスと繋げて出力しています。
_は、戻り値や要素を保存しないという意味です。

結果↓
/kaggle/input/titanic/train.csv
/kaggle/input/titanic/test.csv
/kaggle/input/titanic/gender_submission.csv

最後まで読んで頂き有難うございました。
chatGPT関連デモアプリまとめ

## はじめに
OpenAIのAPIがリリースされて以降、多数のllm関連デモアプリがossとしてリリースされています。特にAzureOpenAIが公開されて以降はマイクロソフト公式のものを中心にchatgptを用いたエンタープライズ向けOSSも多数公開されてきています。
実際に使用してきた経験をもとに、ざっくりとしたわかりやすさ重視で簡単にまとめます。技術、機能的な部分に関しては詳しく言及しませんので、リンク元のgithub等を直接見ていただければと思います。
定期的に更新予定のため、いいね、ストック等していただけると励みになります！
### 対象者
- openaiAPI(AzureOpneAI含む)を用いたOSSについて概要を知りたい人

## 独自データ活用系
- 自前で用意したデータを読み込ませて独自のchatgptを構成するためのデモアプリをまとめます。（モデルの学習を行うわけではない。）
この分野に関しては今後もCognitivesearchを利用したものが主流になると思いますので、MS公式のデモアプリの動向について注視していければと思います。

### 【結論大本命！！！】azure-search-openai-demo

https://github.com/Azure-Samples/azure-search-openai-demo/

AzureOpenAIでgpt3.5turboの公開と同時に公開されたものです。詳しくは<a href="https://techcommunity.microsoft.com/t5/azure-ai-services-blog/revolutionize-your-enterprise-data-with-chatgpt-next-gen-apps-w/ba-p/3762087">こちら。<a/>
社内データを用いたchatgptのpoc等を検討する場合、こちらのアプリを選択すればまず間違い無いんじゃないかと思います。OpenAIが利用可能なAzure環境さえあれば簡単にデプロイできます。
#### 特徴
- Azure CognitiveSearchとgptを組み合わせて**独自データを用いたchat-gpt** を作成できる。
- CognitiveSearchのベクトル検索が超強力。
プレビューリリースされているベクトル検索が利用でき、データのベクトル化も簡単に行えます。


### internal-document-search

https://github.com/Azure-Samples/jp-azureopenai-samples/tree/main/5.internal-document-search

<a href="https://www.microsoft.com/ja-jp/events/azurebase/contents/">AzureOpenAIリファレンスアーキテクチャ<a/>の公開とともにリリースされたもの、先ほど紹介したデモアプリの日本ローカルバージョンの様なものですです。基本的な機能、UIは同じですが以下のような差異があります。
- ベクトル検索非対応
- CosmosDBを用いた履歴管理が可能
- ドキュメントが日本語でわかりやすい

いずれはこれらの差異も埋まるかもしれませんが、jp版は更新がそれほど早くないと思われますので、ベクトル検索を試したい場合は最初に紹介したアプリを利用するのが良いです。


## chatgptクローン系
独自データの利用などはせず、chatgptをAPI経由でセキュアに利用するためのデモアプリをご紹介します。
### chatbot-ui

https://github.com/mckaywrigley/chatbot-ui

- OpenAIAPI/AzureOpneAIAPIを利用して、chatgptライクなchatUIを構築できます。
AzureOpenAIAPIを利用した内部に閉じたセキュアなchatgptを構築する際の、最もシンプルな選択肢になると思います。
チャットのログはキャッシュに保存されます。
- 環境変数の設定で利用するAPIのエンドポイントを変更できるため、langchain等で作成した自前のAPIのフロントエンドとしても活用できるかもしれません。

※こちらのリポジトリは4ヶ月以上更新されていません。
#### azure-chatgpt

https://github.com/microsoft/azurechatgpt

- MS本社公式より公開されているもです。
AzureAD,githubauthを用いた認証機能、CosmosDBによる履歴の管理が標準で利用でき、今後エンタープライズ向けchatgptUIのデファクトスタンダードになるのではないかと思います。
※詳しい中身について確認後追記したいと思います。

## おわりに
かなりシンプルにまとめましたので、アプリの詳細についてもいずれ別記事でご紹介できればと思います。
FreeBSD13.2p2でswayを使ってみる[xwayland disable]

2023/08/12時点、FreeBSD 13.2-RELEASE-p2での話になります。
なにはともあれFreeBSDインストール直後、rootで各種pkgをインストールします。

~~~
# pkg install zsh vim doas
# echo "permit nopass :wheel" >> /usr/local/etc/doas.conf
# pw groupmod wheel -m ログインユーザー名
~~~

rootで必要な事が終わったので作成したユーザーでLoginし直します。

~~~
$ doas pkg install sway seatd dbus foot dmenu-wl firefox fcitx5 fcitx5-configtool ja-fcitx5-anthy gvfs pcmanfm-gtk3
$ pw groupmod video -m ログインユーザー名
$ doas sysrc seatd_enable=”YES”
$ doas service seatd start
$ doas sysrc dbus_enable=”YES”
$ doas service dbus start
~~~
参考:https://docs.freebsd.org/en/books/handbook/wayland/

Handbookの方に下の用に記載あるものの、userすら最初にないので作ります。
~~~
export XDG_RUNTIME_DIR=/var/run/user/`id -u`
~~~

あとは設定ファイル書いていきます。
~~~
$ mkdir ~/.config/sway
$ cp /usr/local/etc/sway/config ~/.config/sway/
$ mkdir ~/bin
$ touch ~/bin/sway
$ chmod +x ~/bin/sway 
~~~

~~~ ~/.config/sway/config #修正と追加
#wayland対応のdmenu-wlに置き換え
#set $menu dmenu_path | dmenu | xargs swaymsg exec --
set $menu dmenu_path | dmenu-wl | xargs swaymsg exec --

#日本語キーボードの設定
input * {
        xkb_layout "jp"
}

#xwaylandを無効。
xwayland disable

#daemonとしてpcmanfmとfcitx5を立ち上げる
exec_always pcmanfm --daemon-mode
exec_always fcitx5 -d --replace
~~~

exec swayと書かれていることが多いが、gvfsを使用して、network共有を使用したいのでdbus-run-sessionで実行
まだ試してないが、gnome keyringも使えるようになるはず。
SDDM,LightDMのようなログインマネージャーはdbus sessionになっているんですかね。
今度、ここら辺のサービス起動まわり調べてみたいです。

~~~ ~/bin/sway
export XDG_RUNTIME_DIR=/var/run/user/`id -u`

export GTK_IM_MODULE="fcitx5"
export QT_IM_MODUKE="fcitx5"
export XMODIFIERS='@im=fcitx'

export QT_QPA_PLATFORM=wayland
export MOZ_ENABLE_WAYLAND=1
export XDG_SESSION_TYPE=wayland

exec dbus-run-session /usr/local/bin/sway
~~~

あと.zshrcに~/binのPATHを追加しているので、$ swayでGUIに移行してます。

~~~ ~/.zshrc
export PATH=~/bin:$PATH
~~~

fcitx5対応のmozcないんですね。Vine linux使ってた時以来のanthyでこの記事書きました。
json1回目

## jsonを理解するのためにデータ構造を理解する必要あり

オンラインの中で一番
一番見やすかったのは
### https://jsoneditoronline.org/

気象庁のデータをどうやってみるのかわからなかったが
オンラインのjson解析ツールで理解できた。

### https://www.jma.go.jp/bosai/forecast/data/forecast/130000.json

今後、インフラエンジニアにも
jsonでの解析が必要となる日が来るはずなので
予習しておきます。
【プラクティス紹介】1分でさらっと分かる「品質バックログ」

## プラクティス名
品質バックログ

## プラクティスの目的・狙い
* プロダクトの品質確保に必要なタスクをあらかじめ盛り込む

## どんな時に使うか
* 品質確保のためリリース前にはやっておきたい、と思っていたタスクが結局実施されない、といった事態が慢性的に続いている時

## 実施手順
1. リファクタリングや高負荷テストといった品質を確保するためには欠かせないが、通常タスクのついでに行うには大きすぎる作業をDEVがPBIとして追加しておく（これを「品質バックログ」と呼ぶ）
1. 何故その作業が必要なのかDEVやSMからPOに説明する
1. 品質バックログのストーリーポイントは時期によって変わりやすいため、こまめに見直す
1. 品質バックログの追加は品質状況に応じて適宜行うか、リリースプランを踏まえ先に追加しておく

## アレンジ例
* スプリントN回おきに品質バックログを処理するための回を設ける、など周期化する
* 全部を一度にやろうとすると作業量が大きすぎる場合は範囲を限定してPBIも分割する

## アンチパターン
* PBIは追加したが、POがその意義を理解していないため、優先順位が低いままで実行されない
* 品質バックログが逆に免罪符となってしまい、本来スプリント中に担保すべきことが行われなくなる

## 参考情報
「品質バックログ」の出典は以下の書籍です（ただし上記の説明は色々付け足しています）

https://www.juse-p.co.jp/products/view/799

## こぼれ話（私的コメント）
アジャイル開発ってQA屋（品質保証）泣かせなんですよね。QA出身の僕が言うのだから間違いないです。既存のメトリクス（品質指標）は軒並み使えなくなるし、スクラムチームの外から第三者的に品質保証するというスタンスもイマイチ、ハマらないし・・・。なのでチームの中でしっかり品質確保してもらいたいところですが、そのための品質活動の痕跡がまた追いにくくて困ります。品質バックログがあればそのあたりが多少は見えるようになるかもしれません。
ピュアなアジャイラーの方には品質はスプリント内で担保すべきものであって、そもそもバックログ化すべきではない、とお𠮟りを受けそうなプラクティスではあります。

　[アジャイルプラクティス一覧へ戻る](https://qiita.com/kakashi_h5/items/20584998c5ca4594b9ea)
Seleniumが本当にバレバレなのか試してみた

# 目的

[以前こちらの記事](https://qiita.com/MOSO1409/items/f5eba26a1cd893626bc7)にてスクレイピングはすぐにバレることを知った
本当にそうなのか試してみたくなったので、実際に試してみた

# 確認手順

- 適当にWebページをつくる
- スクレイピングをして挙動を確認する

# 環境構築

なんでもいいんですが、試しにReactで環境構築します

```powershell
npx create-react-app check-scraping
cd check-scraping
code .
npm run start
```

プロジェクトを作成したら`App.js`を修正します

```jsx
import React, { useEffect } from 'react';

function App() {
  useEffect(() => {
    if (window.navigator.webdriver) {
      alert("Webdriverを検出しました");
    }
  }, []);

  return (
    <div className="App">
      <h1>WebDriver検出テスト</h1>
    </div>
  );
}

export default App;
```

# 実際にスクレイピングする

Anacondaに以前使っていたソースコードが残っていたのでそちらを利用します

```python
import time
from selenium import webdriver

driver = webdriver.Edge()

def main():
    driver.get(url="http://localhost:3000")
    time.sleep(3)
    driver.quit()

if __name__ == '__main__':
    main()
```

# 結果

ちゃんと検出してくれました

ふつーにスクレイピングしたら一瞬でバレますね
![a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3351724/7844a64e-993c-092f-0f52-14c2af45cf5d.png)

# おまけ

`--disable-blink-features=AutomationControlled`を追加することでwindow.navigator.webdriverプロパティを無効にすることができるそうですね。
知らなかったので補足しておきます。（使用時はサイトの利用規約を守ってください）

``` python 
import time
from selenium import webdriver

options = webdriver.EdgeOptions()
options.add_argument("--disable-blink-features=AutomationControlled")

driver = webdriver.Edge(options=options)

def main():
    driver.get(url="http://localhost:3000")
    time.sleep(3)
    driver.quit()

if __name__ == '__main__':
    main()
```
[UE] サブレベルでナビメッシュを持つには

(UE5.1、UE4.27で確認)

# やりたいこと
「ゲームを通してパーシスタントレベルを固定し、サブレベルを読み替えることでマップ遷移を行う」レベル構成だとする。

例えば：
PLv_GameMain　　←常駐
 ├ SLv_Test01_Map (地形データ)　　←マップ遷移ごとにロード/破棄する(以下同)
 ├ SLv_Test01_Ev (イベントアクタ)
 ├ ...
 └ **SLv_Test01_Nav** (ナビメッシュデータ)

というように、**各マップのナビゲーションメッシュをサブレベルとして用意したい**ケースを考える。

# 問題
上記のレベル構成で、以下のように素直にアクタ配置するだけだとうまくいかなかった。

SLv_Test01_Nav
 ├ NavMeshBoundsVolume
 └ RecastNavMesh-Default

調べると、(※結果的に、昔の)UEでは**ナビメッシュボリュームはパーシスタントレベルに配置されていることが前提になっている**とのことだった。
(つまり、サブレベルに配置したナビメッシュは反映されない)

対策として、

- パーシスタントレベルにdynamicボリュームを置く　→さすがに高負荷
- パーシスタントレベルにダミーのボリュームを置くと、サブレベルのナビメッシュボリュームも読み込まれる　→挙動が不安定だった

あたりで、うまくいかない……と思っていたところ、どうやらそもそも古い情報だったのか、以下の解決法が存在した。

# 解決策
ふとプロジェクト設定を眺めていたら、クリティカルなコンフィグがあった。

![ナビゲーションシステム_プロジェクト設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3529609/ed3e92a2-9bc9-6745-b61b-890e5a281d64.png)

プロジェクト設定 - エンジン - ナビゲーションシステム

**サブレベルナビゲーションデータを破棄**
(Should Discard Sub Level Nav Data)
「trueの場合、ロードされたサブレベル内のナビゲーションデータをゲームで無視します」

なんでデフォでtrueなん;;

ということで、こちらのチェックボックスを外すことで、フツーにサブレベルでナビゲーションメッシュを取り扱えるようになった。

# その他の構成
ナビメッシュの設定アクタであるRecastNavMesh-Defaultは、NavMeshBoundsVolumeを置くと**そのときのパーシスタントレベル**に自動生成される。
そのため、「ナビメッシュ用サブレベルにRecast(略)を置くには、ナビメッシュ用サブレベルを(編集時に)パーシスタントレベルにする」必要がある。(多分)

ということで、Navサブレベルはエディタ上で以下のレベル構成にしておき、レベル更新時はこのレベルを開いてナビメッシュを生成するようにすると良さそう。

SLv_Test01_Nav
 ├ SLv_Test01_Map (地形データ)
 ├ SLv_Test01_Ev (イベントアクタ)
 ├ ...

## これは何？
同じく上述のプロジェクト設定に、以下の設定項目がある。

**ナビゲーションの境界レベルでナビゲーションデータをスポーン**
(Spawn Nav Data in Nav Bounds Level)
「trueの場合、ナビゲーションの境界があるサブレベルでナビゲーションデータインスタンスのスポーンを試み、falseの場合、パーシスタントレベルでスポーンします」
※デフォルトでfalse

これをtrueにすれば↑のRecast(略)問題が解決するかと思ったけど、特に影響はなさそうだった。

ランタイムのナビメッシュデータインスタンスがどこに生成されるかの設定？
だとしたらナビデータはサブレベルと一緒に破棄されてほしいので、trueにしておくべきか。(要確認)
propsの型をbooleanに変更する方法

### 前提
1. コンポーネントに react hook form の入力値を渡し、入力の有無によってコンポーネント内で表示する要素の出し分けをしたい。
2. ただ入力の有無がわかればいいのでbooleanに変換して渡したほうがよさそう



ということで、まずコンポーネントの方を次のような感じにする

```tsx:ExampleComponent.tsx
interface Props {
  hasInput: boolean;　//　propsで受け取る値はbool値に
  children?: React.ReactNode;
}

export const ExampleComponent: React.FC<Props> = ({
  hasInput,
  children,
}) => {
  // ... コンポーネントの中身 ...
}
```

ExampleComponentを呼び出す際に以下のようにhasInputを渡します
```tsx:
// ここでsomeValueをbooleanに変換
<ExampleComponent hasInput={!!someValue}> 
  {/* ... */}
</ExampleComponent>

```


`!!`はsomeValueをbooleanに変換するためのものです。someValueがnull、undefined、""（空文字列）、0のいずれかの場合、hasInputはfalseになります。それ以外の場合はtrueになります。

この変更を行うことでコードがより直感的になり、読みやすくなります。

### 詳しく説明してみます
 `!`（論理NOT）：
この演算子は、オペランドの真偽値を反転させます。つまり、trueはfalseに、falseはtrueに変わります。オペランドがtruthyな値であれば、!はそれをfalseに変換します。逆に、オペランドがfalsyな値であれば、!はそれをtrueに変換します。

```js:example
javascript
Copy code
!true       // false
!false      // true
!""         // true
!"hello"    // false
```
`!!`：
二つの!演算子を連続して使うことで、最初の!で変換された真偽値が再び反転され、元の値の真実性を示す真偽値が得られます。

```js:example
javascript
Copy code
!!true      // true
!!false     // false
!!""        // false
!!"hello"   // true
```
したがって、`!!someValue`とすることで、someValueがtruthyな値であればtrueに、falsyな値であればfalseに変換されます。
(未解決) Nuxt3 – useFetch に ランダムなkeyを指定すると2回重複して GET リクエストしてしまう (SSR)

# バージョン

Nuxt 3.6.5 

# NOTE

- SSRでscript直下に書くと2回評価されるとかそれ系かもしれない

# 例

```vue
<script setup lang="ts">
const randomKey = Math.floor(Math.random() * 9999999999999999999999).toString()
await useFetch("https://example.com/", { key: randomKey })
</script>
```

# dev tool の結果

<img width="1435" alt="image" src="https://github.com/YumaInaura/YumaInaura/assets/13635059/19d65001-87e9-4636-b1e9-3ac13bd0ab11">

リクエスト先をログの取れるlocalサーバーにしても確かに2回リクエストされているようだったのでdev Tool の問題ではなさそう


# 挙動

- SSRで起きる
- CSR  ( SPA ) では起きない

nuxt config の例

```
export default defineNuxtConfig({
  ssr: true,
  devtools: { enabled: true },
});
```

# ボタンを押した時の挙動にした場合

ボタンを1回押すごとに1回リクエストされる

```vue
<script setup lang="ts">
function fff() {
  const randomKey = Math.floor(
    Math.random() * 9999999999999999999999
  ).toString()
  useFetch("http://localhost:7001/api/health_check", { key: randomKey })
}
</script>

<template>
  <div>
    <button @click="fff">click</button>
  </div>
</template>

```

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# Twitter

https://twitter.com/YumaInaura
Unityで赤青メガネ(URP/HDRP)

以前、[赤青メガネを使った立体視](https://qiita.com/ELIXIR/items/c9754f360085312f0ce0)の記事を書きましたが、今回はURP/HDRPで使用できるシェーダーブラフを用意しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/1dfdb532-5008-0abb-e103-326b08df7320.png)
使用法は前回と同じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/bcdabdc2-a290-5c2a-a38d-2ed7211c5093.png)

[動画](https://youtu.be/k_OaNccD-aY)