OmniAICreator/Qiita-1.07M huggingface dataset:
Linux Command Historyまとめ

コマンドを覚えたいので一度でも使ったコマンドはできるだけ以下に追加して覚えるようにします。

```bash
- neofetch # Display system information in a visually appealing way. Various flags like --ascii_distro show ASCII art of a specific Linux distribution.

- sudo getenforce, sudo sestatus # Commands related to SELinux, displaying current mode and status respectively.

- apt list --installed | grep <package> # List installed packages and filter results for specific ones, useful for checking if a specific package is installed.
- sudo aa-status # Check the status of AppArmor, a Linux kernel security module.
- sudo systemctl status <service> # Check the status of a system service, e.g., `sudo systemctl status apparmor.service`.
- sudo cat /sys/kernel/security/apparmor/profiles # Display AppArmor loaded profiles.
- sudo ls /etc/apparmor.d/ # List AppArmor profiles stored in its configuration directory.
- sudo aa-disable <profile>, sudo aa-enforce <profile> # Disable or enforce AppArmor profiles, respectively.

- sudo ufw status # Check the status of the Uncomplicated Firewall (UFW).
- sudo iptables -L # List all current iptable rules.
- ufw default deny # Set the default policy of the firewall to deny.
- sudo ufw allow/deny <port> # Allow or deny traffic on specific ports.

- ip addr show # Display all IP addresses associated with all network interfaces.
- ping -c <count> <destination> # Send a specified number of ping requests to a destination to test connectivity.
- systemctl status NetworkManager # Check the status of the NetworkManager service.
- nmcli, nmtui # Command-line and text user interface tools for network configuration.

- man <command> # Display the manual pages of a command, e.g., `man ls`.
- apropos <keyword> # Search the manual page names and descriptions for instances of a keyword.
- find <directory> -name <pattern> # Search for files matching a name pattern within a directory tree.
- cat /etc/passwd | grep <username> # Display the entry from the passwd file for a specific user.
- shopt -s/-u globstar # Enable or disable the globstar shell option for matching files and directories recursively using **.
- sudo find / -name <name> -type d/f # Find directories or files across the entire filesystem with a specific name.
- zcat <file.gz> | nroff -man # Display the manual page from a gzipped file.
```


追加準備
```bash
- cat /etc/os-release
- uname -a
- hostnamectl
- lsb_release -a
- sar 1 5
- sar -b 1 5
- sar -r 1 5
- taskset -c 0 ./program.py &
```
2024/4/22主にITとかセキュリティの記事

サイバー攻撃､｢恐い｣で済ませない経営者の視点 ホラーストーリーを経営計画に落とし込むには(4/20)
https://toyokeizai.net/articles/-/747128

億単位で被害が出ることもサイバー攻撃、「恐い」で済ませない経営者の視点　ホラーストーリーを経営計画に落とし込むには(4/20)
https://news.yahoo.co.jp/articles/c7b9a7403e9589e7528ae79d9833f0565ad129a7?source=rss

リトアニアのユニコーンが手がけるのは安全・高速・安価なVPN Nord Securityが日本市場にかける期待(4/19)
https://techblitz.com/nord-security/

Appleデバイスの「パスワードをリセット」通知にご用心。アカウント乗っ取りを防ぐには？(4/20)
https://www.lifehacker.jp/article/2404-tech-iphone-password-reset-scam/

暫定的に使用不可となっていたPS4版「LittleBigPlanet 3」のサーバとオンラインサービスが無期限停止(4/20)
https://doope.jp/2024/04145092.html

【日本国家の弱点】いまこそサイバー・セキュリティ改革が外交、安全保障、技術開発に不可欠
小谷 賢（ 日本大学危機管理学部教授）(4/20)
https://wedge.ismedia.jp/articles/-/33583

Appleが中国政府の命令でApp StoreからThreadsとWhatsAppを削除(4/19)
https://gigazine.net/news/20240419-apple-whatsapp-threads-china-app-store/

放置したUIフレームワークのバージョンを上げた時の学び(4/19)
https://blog.engineer.adways.net/entry/2024/04/19/160000

生成ＡＩ、事業者指針決定　政府(4/19)
https://www.jiji.com/jc/article?k=2024041901169&g=eco

日本カストディ銀前社長不正、問題ある外注案件を複数確認－第三者委(4/19)
https://www.bloomberg.co.jp/news/articles/2024-04-19/SC4M1PT0AFB400

ＬＩＮＥヤフーに２度目の行政指導　韓国ＩＴ大手〝ネイバー依存〟現時点で「違法状態」のまま運用、改善されるまで利用停止を(4/20)
https://www.zakzak.co.jp/article/20240420-5MOSIPHA35IOBB66E56276J4TI/

情報漏えい問題で総務省が行政指導、LINEヤフーにいったい何が起きているのか？(4/20)
https://dime.jp/genre/1772175/

Broadcom、VMware製品の永久ライセンスのサポート方針を発表(4/19)
https://news.mynavi.jp/techplus/article/20240419-2930650/

GCC諸国は産業の成長を確保するためにサプライチェーンを強化すべき： オリバー・ワイマン(4/20)
https://www.arabnews.jp/article/business/article_117218/

ＳＮＳ投資詐欺横行　投資ブーム乗じ、著名人かたる勧誘メッセージ　中高年の被害多数(4/20)
https://www.sankei.com/article/20240420-VEBNXSXTHFJYNHA7LT6TWE2YLY/

「トロイの木馬があなたのパソコンに侵入し…」　口座から勝手に数百万円送金される　宮崎県でサポート詐欺(4/19)
https://news.livedoor.com/article/detail/26260704/

アクト、【テレビ局にサイバーセキュリティ対策が必要な理由】のホワイトペーパーを公開(4/19)
https://www.mapion.co.jp/news/release/000000142.000076503-all/

監査委員・監査事務局むけ講演「自治体DX・生成AI・デジタル化における監査・内部統制のポイント」：戸村智憲の監査シリーズ（自治体バージョン）をリリース【日本マネジメント総合研究所合同会社】(4/20)
https://japan.cnet.com/release/30966117/?ref=rss

オランダもロシアのスパイ活動のターゲットに(4/19)
https://www.portfolio.nl/news/post7638/

大谷翔平に見えるリスク管理(4/20)
https://blogs.itmedia.co.jp/satou55_makoto/2024/04/post_15.html?ref=rss
[6]Next.jsチュートリアルを進められたのでやってみる(6)データベースのセットアップ

## はじめに
今回の記事では、Next.jsチュートリアル第6章「データベースのセットアップ」を進めていきます。

https://nextjs.org/learn/dashboard-app/setting-up-your-database
#### 前回の記事

https://qiita.com/2201009-kikukawa/items/334d3f079690b609f47f

## chapter6 データべ―スのセットアップ
- プロジェクトを GitHub にプッシュします
- Vercelアカウントをセットアップしデプロイする
- プロジェクトを作成し、Postgresデータベースにリンクします
- データベースに初期データをシードします

### リモートリポジトリの作成
今までの記事で構築したローカル環境と紐づけるリモートリポジトリを作成していきます。
リポジトリ名は自由ですが今回は`Next-tutolial`としました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619847/d66aa0f2-8c67-a883-e09e-f320a1b473b3.png)

### ローカルとリモートの連結
作ったフォルダにcdで移動し、コマンドラインで以下の内容を入力していきます。

```php:ターミナル
git init
git add README.md
git commit -m "first commit"
git branch -M main
git remote add origin git@github.com:ユーザー名/next-todo.git
git push -u origin main
```
リモートリポジトリとローカルの連携が完了しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619847/4e8f6b75-ca15-c552-2f49-23db7637f366.png)

### Vercelアカウントを作成する
以下のリンクにアクセスしてアカウントを作成していきます。
無料のホビープランを選択して名前を入力します。その後表示される画面でGitHubで続行を選択して、GitHubアカウントとVercelアカウントを接続します。

https://vercel.com/signup

アカウントを作成後以下の画面に遷移するのでgitリポジトリをインポートからアカウントを選択します。その後gitアカウントのリポジトリ一覧が表示されるのでデプロイしたいリポジトリを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619847/a568950a-3594-4255-9493-131f74668bde.png)

プロジェクトに名前を付けて、デプロイをクリックします。

![スクリーンショット 2024-04-22 012119.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619847/718ce5ee-e04b-846e-1b3c-b3d20cf2a23e.png)

この画面が表示されればプロジェクトのデプロイ完了です！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619847/98f3ecad-df57-02e7-6342-8b18f3d6c18f.png)

GitHubリポジトリに接続すると、変更をメインブランチにプッシュするたびに、Vercelはアプリケーションを自動的に再デプロイしてくれます。

## Postgres データベースを作成する
次にデータベースを構築していきます、プロジェクトダッシュボードから`ストレージタブ`を選択します。 `「Connect Store」`→ `「Postgres」`→ `「Accept」`を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3619847/9baa0e66-5fae-afb4-a69c-3f5a9f2ee764.png)

データベース名を割り当て、データベースのリージョンが`iad1`になっていることを確認します。確認したら、`「Create」`→`「Connect」`でデータベースに接続します。

接続が完了したらタブに移動し`.env.local`を開きます。
ファイル内容が伏字になっているので画面右のほうにある`Hide secret`を押して`Copy Snippet`から内容をコピーします。
コード エディターに移動し、`.env.example`ファイルの名前を`.env。`に変更し`Vercel`からコピーした内容を貼り付けます。
### 重要 
GitHubにプッシュするときデータベースの秘密が公開されないように、`.gitignore`ファイルに移動して無視されるファイルに`.env`が含まれていることを確認してください。

最後にターミナルで以下のコードを入力して`Vercel Postgres SDK`をインストールします。

```php:ターミナル
npm i @vercel/postgres
```

## データベースをシードする
データベースが作成されたので、初期データをシードしてみましょう。これにより、ダッシュボードを構築するときにいくつかのデータを操作できるようになります。
`/scripts`フォルダーのなかに`seed.js`というファイルがあります、このスクリプトには、`invoices`、`customers`、`user`テーブルの作成とシードの手順が含まれています。

このシードデータを挿入するために、`package.json`を下記のように書き換えます。
```/package.json
"scripts": {
  "build": "next build",
  "dev": "next dev",
  "start": "next start",
  "seed": "node -r dotenv/config ./scripts/seed.js"
},
```
`npm run seed`でシードデータの挿入が完了です。

## おわりに
今回の記事ではプロジェクトのデプロイ、データベースの構築など中々に濃ゆい内容を進めていきましたが、かなりためになる内容でした。
結構長い記事になりましたが、ここまでお疲れさまでした。

## 次の記事
Firebaseのパスワード再設定でちょっとハマった

### 発生している問題・エラー
sendPasswordResetEmailのエラーをtry-catchでcatchできない。


パスワード再設定メールを送信する処理で、「そもそも登録されていないユーザーの場合」、
try-catchで「登録されていません」と表示したかった。

### 結論
存在する/しないが分かってしまうとブルートフォース攻撃の対象になりかねないのでエラー返すのをやめたとのこと
Googleさんより参照）
https://cloud.google.com/identity-platform/docs/admin/email-enumeration-protection?hl=ja#enable

※Firebase→Authenticatin→設定→ユーザーアクション で、メールの列挙型を無効にすればエラー返してくれる？（試していないです）


### errorMessageは''空のまま。
```Dart
            ElevatedButton(
              onPressed: () async {
                // エラーメッセージ
                String errorMessage = '';
                try {
                  await FirebaseAuth.instance
                      .sendPasswordResetEmail(email: _email.text);
                } on FirebaseAuthException catch (e) {
                // ⭐️ここに入らない
                  errorMessage = "エラーが発生しました。";
                  if (e.code == 'invalid-email') {
                    errorMessage = "無効なメールアドレスです。";
                  } else if (e.code == 'user-not-found') {
                    errorMessage = "メールアドレスに紐づくユーザーが見つかりませんでした。";
                  } else {
                    errorMessage = "予期しないエラーが発生しました。";
                  }
                } finally {
                  print(errorMessage);
                  ScaffoldMessenger.of(context).showSnackBar(SnackBar(
                     content: Text(errorMessage),
                 ));
                }
              },
              child: Text("送信"),
            ),```
Flutter で Firebase.initializeApp() が iOS でうまく動かなかった話

# これなに
Android で Firebase が使えるようになったので、 iOS でも試そうと思ったら Firebase 初期化処理で引っかかってしまったので解決した方法をメモした。


# 原因
- VisualStudio で `GoogleService-Info.plist` を `ios/Runner/` に貼り付けたことが原因らしい。
- Xcode で貼り付けないと `project.pbxproj` の更新がされず、正しく plist ファイルを読み込むことができなかったっぽい。


# 解決方法
- Xcode で `ios/` を開く。（FLutter プロジェクト直下ではなく iOS まで潜る）
- Xcode 上で `GoogleService-Info.plist` を `ios/Runner/` に貼り付ける。
- これをもって flutter run でビルドし直すとちゃんと動くようになった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2819748/a86026d7-beae-bd90-7bf1-e3c8862aa117.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2819748/18de3573-d27e-9ebf-5e6a-7c3d600ab291.png)



# 参考：解決までに遭遇したエラー
### Firebase 初期化処理が終わる前に Firebase のメソッドをコール？
なにもないけど、このエラーが出てきた。
```zsh
FirebaseException ([core/not-initialized] Firebase has not been correctly initialized.

Usually this means you've attempted to use a Firebase service before calling `Firebase.initializeApp`.

View the documentation for more information: https://firebase.flutter.dev/docs/overview#initialization
    )
```

### Firebase の再定義エラー
複数定義がある時に出るっぽいエラーではあったものの、そんなものないよ？ってなって頭にハテナマークが浮かんでいた。
```zsh
Failed to build iOS app
Error (Xcode): redefinition of module 'Firebase'
/Users/su3-hokkaido/Github-su3/myapp/ios/Pods/Firebase/CoreOnly/Sources/module.modulemap:0:7


Error (Xcode): failed to emit precompiled header
'/Users/su/Library/Developer/Xcode/DerivedData/Runner-bhnjccbzxqqqqjawkrnzkwnxtbpx/Build/Intermediates.noindex/PrecompiledHeaders/Runner-Bridging-Header-swift_14UCLV31P57KM-clang_2OZP1VBCBKMH4.pch' for bridging header
'/Users/su3-hokkaido/Github-su3/myapp/ios/Runner/Runner-Bridging-Header.h'


Could not build the application for the simulator.
Error launching application on iPhone 15 Pro Max.
```
Googleドライブ上の画像を公開してWebサイトに組み込みたい時

Google Driveのリンクを直接画像として扱う場合は、URLが直接画像へのリンクである必要がある。

`https://drive.google.com/uc?export=view&id=ファイルID`
の形式である必要がある。

※ファイルIDは、https://drive.google.com/file/d/ の後ろの部分


# Next.jsで構築したサイト上に画像を載せる場合
Next.jsではセキュリティ上の理由から、外部の画像ホストを使用する前に設定ファイルで明示的に許可する必要がある。

```next.config.js
module.exports = {
  images: {
    domains: ['drive.google.com'],
  },
}
```
Oracle 19Cの公式ドキュメントを読む　基本の初期化パラメータ編

最近Oracle 19Cの利用を始めたため、公式ドキュメントを少しずつ読む。
個人のメモとして大切な個所は記事に残す。

# Oracle 19Cの公式ドキュメント要約　基本の初期化パラメータ
初期化パラメータでは、主にパフォーマンスの制御などができる

・CLUSTER_DATABASE
→Oracle RAC（Oracleとインスタンスの関係を１対多にする）の使用可否
・COMPATIBLE
→Oracleの新しいリソース使用が可能になる、データベースをダウングレードできる
・CONTROL_FILES
→データベース構造を記述する制御ファイル名をカンマ区切りで指定する
・DB_BLOCK_SIZE
→DBのブロックサイズ（バイト）を指定する。（指定可能範囲は2048~32768）
・DB_CREATE_FILE_DEST
→Oracle Managed Files(データベース管理を容易にするもの)のデフォルト位置
・DB_CREATE_ONLINE_LOG_DEST_n
→Oracle管理の制御ファイルとオンラインREDOログのデフォルトの位置を指定
・DB_DOMAIN
→ネットワーク構造内でのデータベースの論理上の位置を指定
・DB_NAME
→最大8文字のデータベース識別子を指定
・DB_RECOVERY_FILE_DEST
→高速リカバリ領域のデフォルト位置を指定
・DB_RECOVERY_FILE_DEST_SIZE
→リカバリファイルで使用される合計領域に対する制限（バイト）
・DB_UNIQUE_NAME
→データベースに対しグローバルに一意の名前を指定
・INSTANCE_NUMBER
→記憶域パラメータFREELIST GROUPSで作成されたデータベースオブジェクトごとの空きリスト、
グループの1つにインスタンスをマップする一意の番号を指定
・LDAP_DIRECTORY_SYSAUTH
→管理権限を付与されたユーザーに対してディレクトリベースの認可を使用可能または禁止する
・LOG_ARCHIVE_DEST_n
→REDOログ・ファイルのアーカイブ先を指定
・LOG_ARCHIVE_DEST_STATE_n
→、対応する宛先の可用性状態を指定（enable,defer,alternate,reset）
・NLS_DATE_LANGUAGE
→、TO_DATE関数およびTO_CHAR関数によって戻される曜日名、月名および日付の略称
(a.m.、p.m.、AD、BC)に使用する言語を指定
・NLS_TERRITORY
→その地域の第二通貨記号(Euroなど)を指定。
・OPEN_CURSORS
→1つのセッションで同時にオープンできるカーソル(プライベートSQL領域へのハンドル)の最大数を指定。
デフォルトは50。
・PGA_AGGREGATE_TARGET
→インスタンスに接続されたすべてのサーバープロセスが使用できるターゲット集計PGAメモリーを指定
・PROCESSES
→Oracleに同時に接続できるオペレーティングシステムのユーザープロセスの最大数を指定
・REMOTE_LISTENER
→Oracle Netリモートリスナー(このインスタンスと異なるシステム上で実行中のリスナー)のアドレス
またはアドレスリストを解決するネットワーク名を指定
・REMOTE_LOGIN_PASSWORDFILE
→Oracleがパスワード・ファイルを確認するかどうかを指定
shared：一つ以上のデータベースがパスワードファイルを使用可能。
exclusive：１つのデータベースのみがパスワードファイルを使用可能。
none：パスワードファイルは無視される。特権ユーザーはOSによって認証される。
・SESSIONS
→システムに作成できるセッションの最大数を指定。
・SGA_TARGET
→すべてのSGAコンポーネントの合計サイズを指定。
指定しているとDB_CACHE_SIZE、SHARED_POOL_SIZE、LARGE_POOL_SIZE、JAVA_POOL_SIZE、STREAMS_POOL_SIZE
DATA_TRANSFER_CACHE_SIZEが自動チューニングされる。
・SHARED_SERVERS
→インスタンスの起動時に作成するサーバー・プロセスの数を指定。
・STAR_TRANSFORMATION_ENABLED
→コストベースの問合せ変換を、スタークエリーに適用するかどうかが判別される。
・UNDO_TABLESPACE
→インスタンスの起動時に使用するUNDO表領域を指定。

## まとめ
最初に絶対設定変更しなければならない項目はなさそう。
まだよくわかっていない項目もあるので、加筆すると思います。
W32TeXの導入を自動化した

# 1. 動機

以下のページを参考にW32TeXをインストールした際，ファイルの解凍やインストールも自動で実行されれば楽だと思ったこと．

[USBメモリ活用講座【W32TeXポータブル化】](https://www.nagaoka-ct.ac.jp/ec/labo/visu/usb/tex/w32tex.shtml)

# 2. 本論

## ・インストール

以下のコードを保存し，実行する．

```bat:W32TeXinstaller.bat

@echo off
setlocal enabledelayedexpansion

set URL=https://ftp.jaist.ac.jp/pub/CTAN/systems/win32/w32tex/
set files= ^
	unzip.exe ^
	texinstwin.zip ^
	latex.tar.xz ^
	mftools.tar.xz ^
	pdftex-w32.tar.xz ^
	platex.tar.xz ^
	ptex-w32.tar.xz ^
	web2c-lib.tar.xz ^
	web2c-w32.tar.xz ^
	dvipdfm-w32.tar.xz ^
	dvipsk-w32.tar.xz ^
	ltxpkgs.tar.xz ^
	luatexja.tar.xz ^
	luatex-w32.tar.xz ^
	makeindex-w32.tar.xz ^
	manual.tar.xz ^
	newtxpx-boondoxfonts.tar.xz ^
	t1fonts.tar.xz ^
	tex-gyre.tar.xz ^
	txpx-pazofonts.tar.xz ^
	sam2p-w32.tar.xz ^
	uptex-w32.tar.xz ^
	xetex-w32.tar.xz

if not exist W32TeX\Temp (
	mkdir W32TeX\Temp
)

set elements_count=0
for %%i in (%files%) do (
	set /a elements_count += 1
)

set download_count=0
for %%j in (%files%) do (
	set /a download_count += 1
	echo. & echo Downloading %%j [!download_count!/%elements_count%]...
	bitsadmin /transfer W32TeXdownload /priority foreground %URL%%%j %cd%\W32TeX\Temp\%%j > nul
	cls.exe
)

chdir W32TeX\Temp
echo. & echo Extracting files...
unzip.exe texinstwin.zip -d .. > nul
cls.exe

chdir ..
texinstwin.exe %cd%\Temp > nul
echo. & echo Installation finished. Press any key to exit.
pause >nul
```

実行結果
```
...
Add
C:\Users\***\Desktop\W32TeX\bin
or
C:\Users\***\Desktop\W32TeX\bin64;C:\Users\***\Desktop\W32TeX\bin
in the case of 64bit OS
to user's PATH in the control panel.

Installation finished. Press any key to exit.
```

各ファイルの詳細は [``` 00FILES.sjis ```](https://ftp.jaist.ac.jp/pub/CTAN/systems/win32/w32tex/00FILES.sjis) に書かれています．他に必要なファイルがある場合は，コードに追記してください．

ディレクトリー構造は以下のようになりますが， ```Temp\ ``` 以下はダウンロードしたアーカイブファイルなので削除して問題ありません．

```
.
├─ W32TeXinstaller.bat
└─ W32TeX
　　 ├─ bin
　　 ├─ share
　　 │　 ├─ ctxdir
　　 │　 ├─ texmf-context
　　 │　 ├─ texmf-dist
　　 │　 ︙
　　 │　 └─ texworks
　　 │　 　　 ├─ share
　　 │　 　　 ├─ texworks-help
　　 │　 　　 └─ twdata
　　 │　 　　 COPYING
　　 │　 　　 README.txt
　　 │　 　　 texworks.exe
　　 │　 　　 texworks-setup.ini
　　 └─ Temp
```

``` W32TeX\share\texworks\texworks.exe ``` を実行すればTeXWorksが利用できます．

## ・環境変数（Path）追加

コマンドラインによるコンパイルをしない場合，この手順は不要のはずですが，一応記載しておきます．

以下のコードを保存し， ``` W32TeX\ ``` と同じディレクトリーに置いて実行する．

```
.
└─ W32TeX
Path.bat
```

```bat:AddPath.bat

@echo off

set PATH=%PATH%;%cd%\W32TeX\bin;%cd%\W32TeX\bin64

echo. & echo Path added. & echo. & echo Checking files, please wait...

platex.exe --help >nul
if %errorlevel% == 1 (
	echo. & echo [ERROR] platex.exe is not installed.
	goto close
)
dvipdfmx.exe --help >nul
if %errorlevel% == 1 (
	echo. & echo [ERROR] dvipdfmx.exe is not installed.
	goto close
)

echo. & echo OK.
cmd.exe /k cls.exe

:close
echo. & echo The program is closing in 10 seconds...
timeout /t 10 /nobreak >nul
exit
```

実行結果（正常終了時）
```
C:\Users\***\Desktop>
```

これらの環境変数は，コマンドプロンプトを終了すると削除されます．
ChatGTPのAPI使用時 You exceeded your current quota, please check your plan and billing details. For more information on this error, read the docs:https://platform.openai.com/docs/guides/error-codes/api-errors.

## はじめに
ChatGTPのAPIを使ってiOSアプリを作ってみようとしたところ､APIからのレスポンスを確認したら､タイトルのエラーが返ってきたのでメモ

## ChatGTPの通常の課金とAPIの課金は別
APIの課金は別なのが原因でした｡
APIの決済の登録や､いくらまで使えるようにするのかの上限をきめないといけないみたいです｡

試したら追記します｡

## 参考
https://romptn.com/article/2274

https://zenn.dev/reds/articles/b82f0f0a457120

https://qiita.com/orange-user/items/b2ed0ab55fad4615167d
docker composeに対してlocalhostのみアクセス出来るようにしたい！

# やりたいこと
vps内でnginxとdocker composeを起動させ、nginxを介さないとdocker composeにアクセス出来ないようにしたい。

# 前提条件
vps
nginxはvpsに直接インストールされている。
docker composeではweb serverが起動している。

# なぜ記事を書いたのか
まじで見つからなかった。みんなiptableに穴開ける方法かdocker compose内でnginx立てる方法ぐらいしか語ってない。どうして...。

そんな私の備忘録的な記事になります。

# 解決法
簡単でした。docker-compose.ymlでport指定するときに`127.0.0.1:8000:8000`とするだけでした。

以下の画像はswagger-uiを構築した時のdocker composeです。参考程度に...。
```docker
  swagger-ui:
    image: swaggerapi/swagger-ui
    container_name: "swagger-ui"
    ports:
      - "127.0.0.1:12360:8080"
    volumes:
      - ./api/openapi.yaml:/openapi.yaml
    environment:
      SWAGGER_JSON: /openapi.yaml
```

結論からすればnetworkを定義する必要もなければ、internal指定をする必要もなかったわけですね。

nginx側では、普通にlocalhostに通信を流してあげれば出来ました。
便利！

```nginx
location / {
    proxy_pass http://localhost:12360/;
    proxy_http_version 1.1;
    client_max_body_size 150M;
    proxy_connect_timeout 300;
    proxy_redirect off;
    proxy_set_header Host $host;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-Host $host;
    proxy_set_header X-Forwarded-Server $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
```
Prisma+Next.jsで実装したAPIでエラーになった時の対処メモ

[ローカルでは実行できたAPI](https://qiita.com/yhida0702/items/8a8403b842cbb87e320a#api%E3%81%AE%E6%8C%99%E5%8B%95%E7%A2%BA%E8%AA%8D)（`src/pages/api/ramen/index.ts`）が、Vercel上にデプロイすると500エラーになった時の問題解消方法。
![スクリーンショット 2024-04-22 0.25.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366676/19bc0b38-f994-d272-5b86-fb798b2ad890.png)


Vercel上にデプロイしたアプリケーションでエラー発生すると、勝手にログが残ってくれていた。
ありがてぇ。
![スクリーンショット 2024-04-22 0.22.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366676/fe274211-09b4-fcc2-9df0-0ffb195fd975.png)

このエラーを見ると、Vercelのデプロイメントプロセス中にPrisma Clientが自動生成されていないために、古いバージョンのPrisma Clientが使用されていることが問題の原因だった様子。
この問題を解決するためには、ビルドプロセス中にprisma generateコマンドを明確に実行する必要がある。

とのことで…
以下のように書き換え。

```package.json
{
  "scripts": {
    "build": "prisma generate && next build"
  }
}
```

# 挙動確認
問題なく動いた！
めでたしめでたし。
![スクリーンショット 2024-04-22 0.29.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366676/79675175-762c-7846-d944-72434e5ed5b4.png)
[エンジニア面接で答えられますか？] なぜMVCCが必要？

こんにちは、[gccj](https://twitter.com/milegao)です。
今回はエンジニアの面接において、なぜMVCC（多版型同時実行制御、MultiVersion Concurrency Control）が必要であるかについて、ジュニアとシニアの観点から答え方を考えてみます。

# ジュニアの回答例

MVCCは、データベースでの同時実行性能を向上させる技術です。
これにより、多くのユーザーが同時にデータベースを使って作業をしても、パフォーマンスが落ちにくくなります。主に、データの一貫性を保ちつつ、アクセスの競合を減らすために用いられます。



# シニアの回答例
MVCCはデータベースの同時実行制御メカニズムであり、複数のトランザクションが同時に発生する場合のデータの整合性と効率を保つために極めて重要です。
具体的な同時実行のケースを考えると、以下のように分析できます：

- READ x READ：同時にデータを読む操作には競合が発生しないため、MVCCの介入は不要です。
- READ x WRITE：主に読み取り一貫性の問題があり、トランザクション中にデータが変更されると、読み取り結果が不安定になります（例：Non-Repeatable Read）。
- WRITE x WRITE： 二つのトランザクションが同じデータを異なる内容で更新しようとすると、更新の競合が発生します。

それではMVCCこの上記の同時実行時の役割を説明します。
**READ x READはMVCC不要のため説明なし*

## MVCCの役割
### READ x WRITE
1. データのバージョン管理：MVCCでは、データの各バージョンが保存され、読み取りを行うトランザクションは、その開始時点での最新のコミット済みデータのバージョンを見ることができます。これにより、書き込みトランザクションが完了していないデータ（Dirty Data）を読み取ることが防がれます。
2. 読み取りの非ブロッキング：読み取りトランザクションは書き込みトランザクションによってブロックされることなく、データを読み取ることができます。これにより、システムの応答性が向上し、ユーザー体験が改善されます。
3. トランザクションの隔離性の向上：MVCCにより、各トランザクションは他のトランザクションの影響を受けることなく、一貫性のあるデータビューを保持することができます。これにより、Non-Repeatable Readのような問題が解消されます。

### WRITE x WRITE
**もっと精密に言うと楽観・悲観ロックによる制御ですが、それはまた別の記事で話しましょう。*
1. 更新の整合性：複数のトランザクションが同じデータに対して異なる変更を試みる場合、これらの変更がお互いに干渉しないようにする必要があります。MVCCでは、各書き込みトランザクションがデータの新しいバージョンを作成します。これにより、トランザクションが互いに独立して操作を行い、後で競合を解決することが可能になります。
2. 競合の解決：競合が検出された場合、MVCCシステムはタイムスタンプやトランザクションIDを基に、どのバージョンが最終的にデータベースにコミットされるべきかを決定します。これにより、トランザクションが安全にコミットされ、データの一貫性が維持されます。
3. ロックの最小化：従来のロックベースの同時実行制御では、データに対するアクセスを制限するためにロックが使用され、これがパフォーマンスのボトルネックとなることがあります。しかし、MVCCを使用すると、データの書き込みが他の読み取りまたは書き込みトランザクションをブロックすることなく行えるため、ロックが必要な状況が減少します。これにより、デッドロックのリスクが低減され、全体的なシステムのパフォーマンスが向上します。

### 最後
また、MVCCでは、データの各バージョンが自動的に管理されるため、トランザクションは適切なデータバージョンにアクセスすることが保証されます。これにより、開発者はバージョン管理の複雑さを意識することなくアプリケーションを設計することができます。
MySQLの基本的な使い方(起動方法、ログイン、ログアウト、停止まで)

この記事では私の私による私のためのMySQLに関する基本的な操作などを書いておく。
よければ軽くでもいいのでみていってください:v:

# 1.MySQLの起動方法

以下のコードをターミナルで入力して実行する。
```SQL
brew services start mysql@5.7
```
# 2.ログイン
以下のコードをターミナルで入力して実行する。
```SQL
mysql --user=root --password
```
上記のコマンド実行後Enter password:と表示されるので設定したパスワードを入力する。

パスワードを入力後、ログインが成功したら下記のようになる。
(以下の画像はprogateから取ってきた)
![progatesql.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3755384/6c5596d9-7eca-5a23-01b7-f6aa33d9df21.png)

# 3.ログアウト
以下のコードをターミナルで入力して実行する。
```SQL
exit;
```
# 4.MySQLの停止
以下のコードをターミナルで入力して実行する。
```SQL
brew services stop mysql@5.7
```
Raspberrpy Zero 2 W で .NET GUI Application（はきつい）

# まとめ
RaspberryPi Zero 2 Wでは性能的にかなり厳しいです。~~あきらめましょう。~~

# なぜこんなことをしたのか
現在参加しているプロジェクトでRaspberryPi Zero 2 Wを使っているのですが、GUIアプリほしいという話になり、GUi作れるのが自分しかいなかったためです。  

# 検証準備
早速、どんなことをしたのかを以下に書いていきます。
環境は以下の通りです。
- Avalonia UI 11.0.10
- .Net 8.0.2 (Arm64)
- RaspberryPi OS Lite (2024-03-15版)
- Composite出力の720 x 480モニタ
- 16GB microSD

また使用したコードはGithubで公開しています。

https://github.com/aiueo-1234/RaspberryPiGui

映像出力するために、Lite版にGUI機能を追加するという形式をとりました。  
またデスクトップを開いただけでswap領域すら食いつくしたので、swap領域をデフォルトの100から1024にしました。
以下GUI機能追加についての参考サイトです。

https://walking-succession-falls.com/%E3%83%A9%E3%82%BA%E3%83%99%E3%83%AA%E3%83%BC%E3%83%91%E3%82%A4%E3%81%ABGUI%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%99%E3%82%8B/

さらに、.NETは`arm64`バージョンを使用するので[パッケージマネージャが使えません](https://learn.microsoft.com/ja-jp/dotnet/core/install/linux-debian#unable-to-find-package)。手動インストールです。
ちなみにZero 2 wでコンパイルするのは厳しかった（ビルドが永遠に終わらない）のでVisual Studioから`linux-arm64`でコンパイルしたのをRaspberryPiにコピーしました。


# 検証
動かしたアプリのUIはこんな感じです。
![PXL_20240421_152454622.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3476116/a2ced4de-b0b0-67ee-6c4f-d71a4dfeee87.jpeg)

デスクトップ画面すら起動させたくなかったので、`startx {起動したいアプリのパス}`でGUIを起動させました。
アプリの起動自体は30秒ほどで終わりましたが、アプリの動作で困難を極めます。  
さらに、ボタンを押したらテキストが変わる程度のアプリでもボタンを押した後の動作が極めて不安定でした（処理落ちして永遠にアプリの動作が復帰しない）。
【CSS】1つのHTML要素に複数のkeyframeアニメーションを適用させる

# はじめに
HTML要素にアニメーションを当てる際にCSSの`keyframe`を利用する事があると思います。
`animation`プロパティに`keyframe`を指定したCSSを対象のHTML要素にあてることで、アニメーションを付与することができますが、1つのHTML要素に複数の`keyframe`アニメーションを付与したい時にはどうするのか疑問に思ったので調べてみました。


# 結論
シンプルで以外と簡単でした。
`animation`プロパティにおいて「,」で区切ってkeframeを指定するだけでした。
以下2つの`keyframe`（changeColor 、rotate）を指定した例になります。

```css:
.hogeClass {
  /* ～～ */
  animation: changeColor 5s infinite alternate, rotate 5s infinite linear;
  /* ～～ */
}
```

# ソース
試しに上記の方法で`animation`プロパティに2つの`keyframe`を設定したUIを作成してみます。
まずはHTMLを準備しときます。

### ◆ HTML
以下は、`div`タグでCSSを当てるための要素を1つ作成したHTMLです。

```html:index.html
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>keyframes html</title>
        <link rel="stylesheet" href="index.css">
    </head>
    <body>
        <div class="keyframeElement"></div>
    </body>
</html>
```

### ◆ CSS

以下のCSSでは色を変化させるkeyframe（changeColor）、要素を回転させるkeyframe（rotate）の2つを作成しています。
`keyframeElement`クラスに対して、「**,**」区切りで`animation`プロパティにそれらのkeyframeを指定しています。


```css
body {
  padding: 0;
  margin: 0;
  width: 100%;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
}

.keyframeElement {
  width: 50%;
  height: 10vh;
  background-color: red;
  animation: changeColor 5s infinite alternate, rotate 5s infinite linear;
}

@keyframes changeColor {
  0% {
    background-color: red;
  }
  50% {
    background-color: blue;
  }
  100% {
    background-color: green;
  }
}

@keyframes rotate {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}
```


# 実行例
ブラウザからUIの見た目を確認してみます。
`keyframe`で指定した**色の変化**と**UIの回転**の2つのアニメーションが動いている事が確認できました。

![keyframe.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1247619/0d9f9fce-ffbd-791d-8c98-d8c991e3ce9f.gif)
チームビルディングに必要なことはなんだろう

# チームビルディングとは
メンバー１人ひとりのスキルや経験を最大限に活かし、目標を達成できるチームを作り上げる取り組みのこと。新入社員やプロジェクトチーム内のコミュニケーションを活性化するために定期的なミーティングや研修を行ったり、チームの力をより高めるためのゲームを実施すること


## チームビルディングに必要な要素
### 十分なコミュニケーション
「チームが共通の目標を持っている」と各々が認識するためには、メンバー同士のコミュニケーション量の増加が必要になる。
→逆にいうと、共通目標に対する認識が足りていないことは、高確率でプロジェクトの失敗につながる。
- ドラッガー風エクササイズ
1. 自分は何が得意なのか?
2. 自分はどうやってチームの成果に貢献するつもりか?
3. 自分が大切に思う価値は何か?
4. チームメンバーは自分にどんな成果を期待してると思うか?
- インセプションデッキ
5つのWhyと5つのHowに答えていきながらチームで共有のドキュメントを作成することで、プロジェクトの目的や価値、問題点といった全体像を記載し、プロジェクトの進むべき方向性を示す。


### メンバーのスキルの理解
チームで共通の目標を達成するためには、メンバーの経験とスキルを明確にして、チームのなかで共有することがポイント。具体的な役割がはっきりしていることで、効率良く目標達成のための課題を解決ができる
- スキルマップの作成
メンバーでスキルマップを作成することで、チームが持っているナレッジの棚卸しをすると良いかもしれない
　ネットで拾えた良さそうな方法としては、できること/まだできないけどできるようになりたいこと/やりたくないけどできること/できないこと のマトリクスに、それぞれ付箋を貼っていく 等




# 参考
https://www.staffservice.co.jp/client/contents/management/column023.html#:~:text=チームビルディングとは、メンバー,実施したりします%E3%80%82

https://tech.connehito.com/entry/2022/11/21/150828

https://www.agile-studio.jp/agile-practice-map
IP、DNS、ポート番号、それぞれの役割とAWSにおけるサービス

# はじめに
**IP、DNS、ポート番号**、これら三つの要素は、インターネット上でデータが正確な目的地に正確に到達するために連携して動作します。

しかし私も含め初心者の方には馴染みがなく、一度学んでも、次にその単語が出てきたときに正確に思い出せないことがあると思います。

今回は自身の確認をするためにもそれぞれの役割と、AWSにおけるサービスについてまとめておこうと思います。

## IPアドレス
IPアドレス（Internet Protocol Address）は、**インターネット上の各デバイス（コンピュータ、スマートフォン、サーバーなど）に割り当てられる一意の数値のラベル**です。

この**アドレスを通じて、デバイスが他のデバイスと通信を行うことができます。**

IPアドレスは、通常、ドットで区切られた四組の数字で表され（例：192.168.1.1）、それぞれのデバイスを特定します。

## DNS
DNS（Domain Name System）は、**インターネット上のドメイン名をIPアドレスに変換するシステム**です。

人間は数字の羅列よりも文字の方が覚えやすいため、たとえば「www.example.com」というドメイン名を使ってウェブサイトにアクセスしますが、実際にはこのドメイン名が背後でIPアドレスに変換されて通信が行われます。

DNSは、このような**ドメイン名とIPアドレスを対応させる役割**を持っており、「インターネットの電話帳」とも呼ばれます。

## ポート番号
ポート番号は、IPアドレスがデバイスを特定するのに対し、**そのデバイス内で稼働している特定のプログラムやサービスを識別するために使用**されます。

**一つのIPアドレスのもとで複数のプログラムがネットワーク通信を行う場合、どのプログラムがそのデータを受け取るべきかを区別するためにポート番号が必要**です。

例えば、ウェブサーバーは通常ポート80（HTTP）または443（HTTPS）を使用し、メールサーバーはポート25（SMTP）を使用します。

## それぞれの関係性
これら三つの要素は、インターネット上でデータが正確な目的地に正確に到達するために連携して動作します。

**IPアドレスが「どの家に送るか**」を指定し、**ポート番号が「その家のどの部屋に送るか**」を指定します。**DNSは、人間が覚えやすいドメイン名を使って**、これらの数値（IPアドレス）を検索する手助けをします。

# AWSにおけるサービス
AWS（Amazon Web Services）は、さまざまなネットワーキングコンポーネントとサービスを提供しており、これには**IPアドレス、DNS、ポート番号と類似または関連する機能**を持つものが含まれます。

ここではそれぞれの概念に近いAWSのサービスや機能を説明します。

### IPアドレス
- #### Elastic IP
  AWSで提供されるElastic IPは、AWSクラウド内のリソース（主にEC2インスタンス）に割り当てることができる**静的な公開IPアドレス**です。
このIPアドレスはユーザーが管理し、必要に応じて異なるインスタンスに割り当て直すことができます。これにより、柔軟にアドレスを再配置することが可能です。
 
- #### VPC（Virtual Private Cloud）
  VPC内でサブネットを定義し、それぞれのサブネットに**プライベートIPアドレスの範囲を割り当てる**ことができます。
これにより、AWS内のネットワーク構造をカスタマイズし、リソース間の通信を管理できます。

### DNS
- #### Route 53
 Amazon Route 53はクラウドDNSサービスで、**ドメイン名の登録**やDNSルーティング、健康状態チェックを提供します。
 
 Route 53はDNSクエリに応じて適切なIPアドレスを返すことで、適切なエンドポイントにルーティングします。

### ポート番号
- #### セキュリティグループ 
 AWSのセキュリティグループは、**特定のポート番号に対するアクセスを許可または拒否するルールを設定**することで、インバウンドおよびアウトバウンドのトラフィックを制御します。
 
 例えば、HTTP通信を許可するためにポート80を開ける、SSHアクセスのためにポート22を許可するなど、特定のサービスに必要なポートを開閉できます。

# まとめ
IPアドレス、DNS、ポート番号の共通点は、すべてインターネットプロトコルスタックの一部であり、**ネットワーク上でのデータ通信とリソースの識別に不可欠な要素である**という点です。

これら三つの要素は、インターネット上でデータパケットが正しい目的地に正確にルーティングされるために使用されます。

IPアドレスはデバイスを識別し、ポート番号はそのデバイス内の特定のアプリケーションまたはサービスを識別し、DNSは人間が覚えやすいドメイン名をIPアドレスに変換して通信の効率を向上させる。
**それぞれが単独で機能するだけでなく、連携してネットワーク通信を支える基盤として機能しています。**

そのため初心者の内はどの部分がどの機能によるものかが、判別しにくいと思います。
その見分け方の参考になれば幸いです。
Jenkins インストール

# 初めに
Windows10へJenkinsのインストールを行う際、準備をしないと遠回りしてしまいます。
手順を記述しておきます。

# ダウンロード
Jenkinsのダウンロードをしておきます。
Jenkinsのオフィシャルページに行きます。
https://www.jenkins.io/


ダウンロードページからWindows用を取得します。
https://www.jenkins.io/download/

# インストール前準備
jenkinsのための権限が必要ですが、無制限に設定するのはセキュリティ的に良くないため、インストール前にJenkins用のユーザーを追加することにします。

## ユーザー追加
###
設定から [アカウント] 選択し、[ファミリとその他のユーザー] を選択します。
[他のユーザー] の、[その他のユーザーをこのPCにの追加] を選択します。 

<img max-width="100%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547019/2060a8f2-9f2f-85c2-6347-60438fcda385.png">

####
[このユーザーのサインイン情報がありません] を選択し、
次のページで、[Microsoft アカウントを持たないユーザーを追加する] を選択します。
<img max-width="100%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547019/626ad0c6-e899-d6c8-feb3-161fa71985b6.png">
<img max-width="100%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547019/7b285f69-80f6-e221-a7a3-d006d12723a5.png">

###
ユーザー名とパスワード等を設定して下さい。
<img max-width="100%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547019/505878ac-72fd-8a50-54ae-6a1d250dcea9.png">

### 特権の付与:
対象のユーザーに[サービスを起動する権限]を追加します。

####
コントロールパネルを開き、「管理ツール」を選択します。

![05_control.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547019/6922b2c0-854f-3c3b-fd2b-4dd7580dbbaf.png)


「ローカルセキュリティポリシー」を開き、「ユーザー権利の割り当て」を選択します。

![06_user_account.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547019/bec07170-cb45-577c-fb07-3b05cc827038.png)

「サービスとしてログオン」の権利を確認し、この特権を付与します。
![07_service.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547019/6a9a5089-c58e-7a85-0c37-4b681ca52007.png)


## JAVAのインストール

対応Javaが限定されているようなので、バージョンがあっていない場合は、必要なJavaを入れておきます。

今回は、Microsoft Build of OpenJDKをwingetでインストールします。

```powershell
winget install Microsoft.OpenJDK.21
```

インストール先フォルダをJAVA_HOMEに設定しておきます。


# インストール

ダウンロードしたインストールファイルを使用してインストールします。
前もって設定しておいたユーザー名とパスワードを使用して下さい。
インストーラはJAVA_HOMEを参照するので、上記で設定していればそれが使われるはずですが、違う場合は正しいフォルダを設定して下さい。
※ 次の手順（JENKINS_HOMEの変更）はスキップしていも良いです。

## JENKINS_HOMEの変更

デフォルトの場合、JenkinsのHOMEがインストール先の配下に設定されてしまうのが、気になるため、設定を変更しておきます。

C:\Program Files\Jenkins
jenkins.xml
以下の行の値を任意の位置に変更します。
```xml:jenkins.xml
  <env name="JENKINS_HOME" value="%LocalAppData%\Jenkins\.jenkins"/>
```

## Jenkins初期起動
JenkinsのHOMEディレクトリを開くと、secretsディレクトリがあります。
そこにinitialAdminPasswordがあり、初期パスワードがあります。
初期パスワードをコピーしておきます。

1. http://localhost:[設定したポート番号] にアクセスします

1. Unlock Jenkins画面で初期パスワードを入力して下さい

1. Customize Jenkins画面でプラグインを選択します
とりあえず、無難に「Install suggested plugins」を選択しておきます

1. 「Create First Admin User」画面でユーザーを作成して下さい


以上で、初期設定は完了です。
JetpackComposeで指でポイントを動かすSlider

# Slider
サクッとSliderの使い方を紹介します。

```
        var sliderPosition by remember { mutableStateOf(0.0f) }
        Slider(
            value = sliderPosition,
            onValueChange = { sliderPosition = it }
        )
        Text(text = sliderPosition.toString())
```


![スクリーンショット 2024-04-21 22.48.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2394054/27bd4a92-e11c-6e0d-352a-2ddb863f168d.png)



sliderPositionの値を変えることでスライダーの配置を変えることができます。
指定できる数は０f〜１fで小数点で細かく指定することもできます。
ここから、*colors*をSliderColorsという型で指定することで、スライダーのカラーを指定できます。


また、RangeSliderという範囲をスライダー指定できるものを使えば、両サイドからの指で動かせるポイントを使ったスライダーを実装できます。

# 参考
https://developer.android.com/develop/ui/compose/components/slider?hl=ja
ライントレースってなんだろう

# ライントレース
コースに描かれた黒い線にそってロボットを走らせること。（参考： https://my-laboratory.jp/line-trace/ ）
カラーセンサで色や反射光をキャッチし、黒い線を見つけたらモーターの駆動方法を変えてロボットの進行方向を変化させる。
カラーセンサーが黒色の線を見つけるということは、反射率の値が小さくなるということなので、もしカラーセンサーの反射光の値が小さくなったときに、モーターの動きを変更するというプログラムをつくることによって、ロボットの動きをコントロールすることができる。

# 制御方法(P制御・PID制御)
ロボコンではフィードバック制御で滑らかなライントレースを行うことにより、スピードや安定性を向上させることができる。
簡単なライントレースを行うプログラムを作る場合には、カラーセンサーで路面の明るさをみて、「暗い場合」と「明るい場合」で動きを変えてライントレースを行うのが一般的（オンオフ制御と呼ばれる）
このようなシンプルなプログラムでもライントレースは可能だが、スピードや安定性に欠ける。
（参考：https://afrel.co.jp/product/spike/technology-spike/prime/competition/50348/ ）

## P制御
Proportional制御（比例制御）。
P制御は最も基本的な制御内容であり、偏差に比例するよう操作量を増減させる方法。
偏差が大きいほど応答値は急峻に指令値に近づき、またP制御のゲインを大きくすることでその作用は強く働く。
ただし、ゲインを大きくしすぎると応答値が振動的になるため、振動が発生しない範囲での調整が必要。また、応答値が指令値に十分近づくと同時に操作量が小さくなるため、重力や摩擦などの外乱がある環境下では偏差を完全に無くせない。制御を行っても偏差が永続的に残ってしまうことを定常偏差と呼ぶ。
（参考： https://freelance-aid.com/articles/3227.html#:~:text=紹介しましょう%E3%80%82-,比例制御（P制御）,の調整が必要です%E3%80%82 ）

## PID制御
PID制御はP制御に積分（Integral）と微分（Differential）を組み合わせたもの。
制御では偏差の時間積分、つまり制御開始後から生じている偏差を蓄積した値に比例して操作量を増減させる。

### I制御
P制御と組み合わせることで、外乱によって生じた定常偏差を埋めることができる。I制御のゲインを強くするほど定常偏差を速く打ち消せるが、ゲインが強すぎるとオーバーシュートやアンダーシュートが大きくなるので注意する必要がある。極端な場合は制御値が収束しなくなる可能性もあるため、I制御のゲインは慎重に選択することが重要。

### D制御
P制御やI制御では、オーバーシュートやアンダーシュートを繰り返しながら操作量が収束していくが、それでは操作に時間がかかってしまう。そこで、急激な変化をやわらげ、より速く目標値に近づけるために利用されるのがD制御
D制御は、偏差の微分に比例するため、偏差が縮んでいるなら偏差が増える方向に、偏差が増えているなら偏差が減る方向に制御を行う。P制御とI制御の動きをやわらげる方向に制御が入るため、オーバーシュートやアンダーシュートを抑えられるようになる。
ただし、D制御を入れると応答値が指令値に近づく速度は遅くなるため、安易なゲインの増加には注意が必要。


# 制御性能の評価基準
- システムの安定性
- 追従精度
- 応答速度
- オーバーシュート・アンダーシュートの有無
- 外乱への感度
- 特性変動への感度
（参考： https://controlabo.com/control-performance/ ）

# 用語集
## ゲイン
制御対象の応答（車の例ではスピード）を一定量変化させるために必要な制御出力（車の例ではアクセルの踏み込み量）の割合を制御ゲインと表現する。
## オーバーシュート
目標値に到達した後、現在値が目標値を超えて行き過ぎる状態。
## アンダーシュート
矩形波（方形波）の立ち下がり部分において、波形が定常値となる基線を下回ること
## ステアリング
乗り物の進行方向を任意に変えるためのかじ取り装置のこと。日本語の専門用語では「操舵装置」という。
[Python] 次元削減の実装 (PCA/ t-SNE/ UMAP)

# はじめに
>次元削減（じげんさくげん、英: Dimensionality reduction、dimension reduction）とは、高次元空間から低次元空間へデータを変換しながら、低次元表現が元データの何らかの意味ある特性を保持することである。
出典：[Wikipedia](https://ja.wikipedia.org/wiki/%E6%AC%A1%E5%85%83%E5%89%8A%E6%B8%9B)


## PCA
**主成分分析（principal component analysis; PCA）**

```
pip install scikit-learn
```

```python
from sklearn.decomposition import PCA

reducer = PCA(n_components=5) # 主成分数を指定
res = reducer.fit(array)
```

## t-SNE

```
pip install scikit-learn
```

```python
from sklearn.manifold import TSNE

reducer = TSNE(n_components=2)
res = reducer.fit_transform(array)
```

## UMAP

```
pip install umap-learn
```

```python
import umap

#上手く行かなかったら以下でリトライ
#import umap.umap_ as umap

reducer = umap.UMAP()
res = reducer.fit_transform(array)
```


## (おまけ) k-meansクラスタリング
```python
from sklearn.cluster import KMeans

pred = KMeans(n_clusters=8).fit(array) # クラスター数を指定
labels = pred.labels_
```


## 可視化
```python
import matplotlib.pyplot as plt

fig = plt.figure(figsize=(3,3))
ax1 = fig.add_subplot(111)

plt.scatter(
    x=res[:,0], 
    y=res[:,1],
    alpha=1,
    s=0.1
)
plt.show()
```

## `pandas.DataFrame`を用いる場合

```python
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from sklearn.manifold import TSNE
import umap.umap_ as umap
from sklearn.cluster import KMeans

array = np.array(df)

reducer = PCA(n_components=5) 
res = reducer.fit(array)

pred = KMeans(n_clusters=8).fit(array)
labels = pred.labels_
```

```python
df['PCA_one'] = res[:,0]
df['PCA_two'] = res[:,1]
df['kmeans'] = labels


fig = plt.figure(figsize=(3,3))
ax1 = fig.add_subplot(111)

plt.scatter(
    x=df['PCA_one'], 
    y=df['PCA_two'],
    alpha=1,
    s=0.1,
    c=df['kmeans'],
    cmap='tab10'    
)
plt.show()
```
Python Simplenamespaceの利用

[SimpleNamespace](https://docs.python.org/ja/3/library/types.html#types.SimpleNamespace)を使うと、辞書型にkeyを使わずに参照をすることができる。

ex. configという辞書を作りたい時
従来: 
```py
config = {}
config['abc'] = '001'

```
であるが、SimpleNamespaceを使うと、
```py
from types import SimpleNamespace

config = SimpleNamespace()
config.abc = '001'
```
のようにかけて楽である。
OutSystemsでシーケンス番号管理

# OutSystemsでシーケンス番号管理

### 目的
EntityアクションのGetForUpdateの動作を確認し、
シーケンス番号を管理できるか検証すること

### 環境
- OutSystemsの無料アカウント
  - Service Studio
  - [Sleep（Forge）](https://www.outsystems.com/forge/component-overview/1244/sleep-o11)

### 実装方法
1. シーケンス番号管理用のEntity作成
2. GetForUpdate後にSleepするアクション作成（アクションA）
3. GetForUpdate後にSleepしないアクション作成（アクションB）
4. アクションA実行後にアクションBを実行
4. アクションAの更新が完了してからアクションBがシーケンス番号を取得する
4. 目的以外のシーケンス番号は更新されていないことを確認する

### 実装詳細
<iframe width="560" height="315" src="https://www.youtube.com/embed/_2N-V7_7430" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" loading="lazy" allowfullscreen></iframe>

:::note warn
GetForUpdateのタイムアウト時間はプラットフォーム全体のデフォルトのクエリのタイムアウトが使用されているはずだが、個人環境のため確認できていません（[公式](https://success.outsystems.com/ja-jp/support/troubleshooting/application_runtime/timeouts_under_the_hood/#section-4)）
:::
「Maaaring makita pa ba ang dagat」をタガログ語Universal Dependenciesで解析する

Angelina Aquino, Franz de Leon『[Parsing in the absence of related languages: Evaluating low-resource dependency parsers on Tagalog](https://aclanthology.org/2020.udw-1.2)』を横目に、[3月18日の記事](https://qiita.com/KoichiYasuoka/items/0671e0088bbe24151868)の例文に対応する「Maaaring makita pa ba ang dagat」を、タガログ語Universal Dependenciesで解析してみた。

```
# text = Maaaring makita pa ba ang dagat
1	Maaaring	maaaring	ADV	_	_	2	advmod	_	_
2	makita	kita	VERB	_	_	0	root	_	_
3	pa	pa	ADV	_	_	2	advmod	_	_
4	ba	ba	PART	_	_	2	mark	_	_
5	ang	ang	ADP	_	_	6	case	_	_
6	dagat	dagat	NOUN	_	_	2	nsubj	_	_
```

![UD_Tagalog.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/428317/eae7da8d-c78b-5982-a312-b9e0dab669f3.png)

文頭の「Maaaring」を1語とみなすべきか、それとも「Maaari」「-ng」の2語に分けるべきか悩ましい。あるいは「Maaaring」を1語だとみなした場合でも、LEMMAを「maaaring」にするか「maaari」にするかが分からない。このあたり、Angelina Aquinoは何も示してくれてないので、私(安岡孝一)としてはエイヤっと1語にして、LEMMAも「maaaring」にしておいた。

ただ、私が見る限り、少なくともこの例文に関しては、タガログ語とイラヴ語で言語構造が違う。たとえ語順を無視したとしても、グラフ同型にするにはノードの加除が必要だ。残念ながら、タガログ語Universal Dependenciesの知識は、イラヴ語への転用が難しそうである。
Proxmox のアップデート情報を素早く知る（フォーラム・gitからの通知）

## TL;DR

- この[記事](https://qiita.com/oishi-d/items/68185ad4b69c3f7b1a8e)で記載したRSSではメジャーバージョンアップ時の通知しか受け取れなかった。
- マイナーバージョンアップや、新機能の追加を素早く知るための方法の検討
  - 公式コミュニティフォーラムからのメール通知
  - gitのリポジトリのRSS

## 概要

以前、以下の記事を書きました。
この中で、[my.proxmoxのRSS](https://my.proxmox.com/en/announcements/rss)を登録しておけば、機能更新などの情報をキャッチアップできると思っていました。
このRSSはメジャーバージョンアップのリリース時にだけ更新されます。

https://qiita.com/oishi-d/items/68185ad4b69c3f7b1a8e


ですが、以下記事の機能追加のように、マイナーバージョンアップだけど大きな変更がある場合があり、その場合に上記RSSではキャッチアップすることができません。
今回も機能追加の認識はあったのですが、てっきり8.2（メジャーバージョンアップ時）で来ると思い込んでいましたが、リリースされたのは3/28。
半月以上気が付けていませんでした。

https://qiita.com/oishi-d/items/0cc452a022fa1ea07a7b


なので、これらの情報を素早く・確実にキャッチアップする方法を検討しました。


## コミュニティフォーラムのメール通知
機能追加などがされる場合、コミュニティフォーラムに新規スレッドが立ちます。なので、その際に通知が受けれるようにします。


[本家コミュニティフォーラム](https://forum.proxmox.com/)の各フォーラムから、`Watch`を選択。



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2459468/ea66acb9-2b86-b0eb-f203-c327d0bd8ebf.png)


`NEw threads`、`Alerts`、`Emails`、を選択して`Watch`を選択。
※実際、ここはお好みですが、メッセージは新機能・変更に対する反応がほとんどなので、スレッドにしました。
※アラートはフォーラムに来ないと気が付けないのでメールがメインですが、一応付けました。




![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2459468/43476849-148a-db7e-76ad-bedfbe658a7d.png)

各フォーラムごとに設定しなければいけないのは面倒ですが、利用しているソリューション（PVE・PBS・PMG）や言語（英語・ドイツ語）の取捨選択ができると思えばこのほうが便利かもしれません。


## gitのリポジトリのRSS
:::note info
一応情報として書きましたが、正直微妙な気がしています…
:::



Proxmox用のgitのリポジトリがあります。
そこのRSSから通知を受けることもできそうです。

https://git.proxmox.com/?p=proxmox-ve.git;a=summary

画面右下の`RSS`をRSSリーダで登録。



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2459468/31648161-2f9e-9b4a-f6f9-461c26613d73.png)



こちらはコミュニティフォーラムと違い、変更内容の解説などがないのですが、リリース前の情報（執筆次点だと8.2とか）の動きを垣間見ることが出来そうです。
問題はProjectsがいっぱいあるので、それらを登録していかないといけないこと。



### 感想
Proxmox本家内でRSSとメール通知が入り混じっており、どちらかに統一してほしいな…という思いました。
どちらかというとメールよりはRSSのほうが個人のデバイス/アカウントでも認識しやすいのでありがたいのですが、最近はRSSも対応が減ってきている（Windows 10のOutlookからRSSフィードがなくなっていた）みたいなので、悩ましいなと。




## 参考

https://forum.proxmox.com/


https://git.proxmox.com/?p=proxmox-ve.git;a=summary
CISA試験アップデート情報（2024年4月）

# はじめに

CISA試験についてアップデートがあったので記事にしてみました。

https://support.isaca.org/s/article/CISA-Job-Practice-Update-2024

# Who am i ?

しがないエンジニアです。

# この記事の想定読者

 - CISA試験について知りたい方
 - その他

# そもそもCISA試験とは？

CISA試験とはISACAという組織が実施している資格試験でCertified Information Systems Auditorの略です。

https://www.isaca.org/credentialing/cisa?utm_source=google&utm_medium=cpc&utm_campaign=CertBAU&utm_content=sem_CertBAU_certification-cisa-asia-exam-google&cid=sem_2006815&Appeal=sem&gad_source=1&gclid=Cj0KCQjw8pKxBhD_ARIsAPrG45kRXQwC9M9MbTv_1bpeYTr0_sYGUGzeMdmUXfRcQmPjdkjG_RRO_A8aAsgAEALw_wcB

日本ではIPAの試験に監査の試験がありますが、それの海外版に近いイメージです。ISACAの試験はISC2よりも古いようで、他の人に聞いた感じでは、組織によってはISC2よりもISACAの方が広く知られていることもあるらしいです。確かに監査の業界では取得している人が多い感じ印象を受けます。

ISACAのCISA試験については教材をウェブから注文（個人輸入）をして取り寄せるか、もしくはAbitusという会社の教材を使って勉強をするかの2択だと思います。なお、ISACAのCISA試験以外（例えばCISMなど）についてはAbitusは現状（2024年4月現在）サポートしていなかったと思います。

https://www.abitus.co.jp/cisa/

# 本題

さて、前置きが長くなってしまいましたが本題に入りたいと思います。ISACAのページにアクセスすると、どうやら2024年の8月から試験が新しくなるようです。約5年ぶりの更新ですかね。出題比率に若干の変更があるようですが、ドメインの変更についてはないように見受けられます。ただ具体的な中身については現状よくわかりません。

https://support.isaca.org/s/article/CISA-Job-Practice-Update-2024

今後、どんなアップデートがあるかについては注視していこうかなと思います。

# 最後に

5年ぶりの改訂ということで。勉強の一助になれば幸いです。
基本設計について学んだことをアウトプットしました

現在、案件で上流工程のサポートとしてアサインしております。
理解が不足している箇所や分からないことがまだまだ多いため、個人で学習した内容を備忘を兼ねてアウトプットしたいと思います。

# 基本設計とは

> 基本設計はビジネスサイドの要件定義を実現させるために、エンジニアサイドでシステムに実装する機能を明確化、具体化していく工程です。

https://qiita.com/KNR109/items/5d545903ec7fef85cd37#:~:text=%E5%9F%BA%E6%9C%AC%E8%A8%AD%E8%A8%88%E3%81%AF%E3%83%93%E3%82%B8%E3%83%8D%E3%82%B9%E3%82%B5%E3%82%A4%E3%83%89,%E5%8C%96%E3%81%97%E3%81%A6%E3%81%84%E3%81%8F%E5%B7%A5%E7%A8%8B%E3%81%A7%E3%81%99%E3%80%82

要件定義で決めた内容に対して「画面」「機能」「データ」を設計し、実現可能性を検討する項目と解釈しました。
基本設計は「外部設計」とも呼ばれ、**ユーザーから見た時の動作を決める工程**になります。
上記に添付している @KNR109 さんの記事がめちゃイメージしやすかったです。
ありがとうございます！

# クライアントに何をアウトプットする必要があるのか？

以下、代表例になります。
- システム構成図
- 機能一覧
- 画面一覧
- 画面遷移図
- データフロー図
- APIドキュメント

基本設計はユーザーから見た時の動作を決める工程と書いていました。
そのため、個人的には「画面遷移図」と「機能一覧」をメインにクライアントと交渉を進めていけば比較的イメージがしやすいかなと思ってます。
また基本設計ではどうしてもドキュメントが増える傾向にあります。
ドキュメントを作成・クライアントと交渉している段階では良いのですが、詳細設計以降で陳腐化する傾向もあると聞いてます。
そのため、個人的には[Figma](https://www.figma.com/ja/about/)のデザイン作成ができるようになれば、「画面一覧」「画面遷移図」「機能一覧」が1つのツールで完結できそうなので、陳腐化のリスクは軽減できそうだなと考えてます。上流工程の学習と並行して使える様に鍛錬していきたいです。

https://www.figma.com/ja/about/


# クライアントと何をコミットするべきか？

### 1. 要件の遵守
基本設計は、ユーザーの要件と期待に基づいていることを確約していきます。
そのため、システムが顧客の要求事項を満たすことを明確に示す必要があります。


### 2. システムの機能と特性
基本設計は、システムの機能と特性を定義していきます。
各機能がどのように実装され、それらが顧客の期待に応えるかを明確に示す必要があります。


### 3. プロジェクトのスケジュールとリソース
基本設計は、プロジェクトのスケジュールとリソースの見積もりを提供していきます。
クライアントと「実現可能性」について協議し、開発の進行状況やリソースの適切な割り当てをしていきます。


### 4. 変更管理と品質保証
基本設計は、変更管理と品質保証のプロセスを明確に示します。
システムが開発中に変更された場合に備え、品質を維持する方法を示します。


### 5. サポートと保守
基本設計は、システムのサポートと保守に関する計画を提供します。
システムが適切に維持され、必要な修正やアップデートが行われることを確認します。


# さいごに
上流工程は覚えることや考えることが多岐に渡るため、日々インプットとアウトプットをしながら少しずつ覚えていきたいです。また、本記事は学習したこと、実体験をしたことをベースに順次アップデートをしていく予定です。
今回の投稿は学習をしていく上で「個人的」に必要だと思った考えをアウトプットしております。もし「なんか考えが違うな」とか「過不足あるよ」があれば、アドバイスをいただけると大変嬉しいです。

最後までご覧いただきありがとうございました。

参考になった記事

https://qiita.com/KNR109/items/5d545903ec7fef85cd37#:~:text=%E5%9F%BA%E6%9C%AC%E8%A8%AD%E8%A8%88%E3%81%AF%E3%83%93%E3%82%B8%E3%83%8D%E3%82%B9%E3%82%B5%E3%82%A4%E3%83%89,%E5%8C%96%E3%81%97%E3%81%A6%E3%81%84%E3%81%8F%E5%B7%A5%E7%A8%8B%E3%81%A7%E3%81%99%E3%80%82

https://qiita.com/Saku731/items/741fcf0f40dd989ee4f8

https://qiita.com/minimumskills/items/8e5863292b9215a2b29f

https://qiita.com/Soysoy11110000/items/0fb607ddacf5e9c1e8db
【Laravel】AWS S3に画像を保存

# 開発環境
Widows11
Laravel10

# ドキュメント

https://readouble.com/laravel/10.x/ja/filesystem.html

# S3 バケット作成

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784589/38229fe7-6ae2-58fb-a879-cc1c8d71e85a.png)

# S3操作を行うパッケージをインストール

```
composer require league/flysystem-aws-s3-v3
```
# .envを編集

```php:.env
AWS_ACCESS_KEY_ID=アクセスキー
AWS_SECRET_ACCESS_KEY=シークレットアクセスキー
AWS_DEFAULT_REGION=ap-northeast-1
AWS_BUCKET=バケット名
AWS_USE_PATH_STYLE_ENDPOINT=false
```

# コントローラー作成
```php:ImageUploadController.php
    public function imageUpload(Request $request)
    {
        $result = Storage::disk('s3')->put('/', $request->file('file'));

        if ($result) {
            return 'アップロード成功';
        } else {
            return 'アップロード失敗';
        }

    }
```
`put()`
第一引数：ファイル保存場所
第二引数：保存するファイル

# ルートを追加

```php:routes/api.php
Route::post('image_upload', [ImageUploadController::class, 'imageUpload']);
```

# Postmanで実行
## Headers
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784589/8253f46e-9727-0503-3c62-586d7e13604d.png)

`Content-Type`:`multipart/form-data`を追加

## Body

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784589/73982376-1570-feba-82fd-ee2182cba3c4.png)
・`form-data`を選択。
・`Key`に`File`を設定
`Key`に任意の名前（ここではfile）を指定することでLaravel側で受け取れる。

```php:
$request->file('file')

// Keyをimageにした場合
$request->file('image')
```
・`Value`で任意のファイルを選択

## 実行

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784589/fd136ea3-e92a-0168-7202-823d4a307932.png)

# S3で確認

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784589/0d0ef25e-f3ad-e3bd-ee0d-12279b5ef6ea.png)



# 参考記事

https://qiita.com/kouki_o9/items/dcc40b30924fd3b30787

https://taishou.ne.jp/laravel-s3-connect/

https://www.geekfeed.co.jp/geekblog/laravel_s3
React公式ページで学んでみた15（備忘録）

# はじめに
初めまして！
エンジニアになって数年、今まで本を読むだけでしたが、もっとプライベートで楽しみながら成長したい！自分が学んだ足跡を残していきたい！と思い記事を書きました！
最終的には自在に開発できるようになりたいと思っています。:triumph:
いろいろな記事を参考にさせてもらっています。:bow_tone2:
その中でもこれってどういう意味？とかつまづいたところを念入りに書いていこうかと思います。:fist:

# 今回の目的
前回の続きです。今回は「ref で値を参照する」。被る部分もあると思いますが、後で振りかえって深掘りするきっかけになるのが理想です。細かく書くと大変なのであっさりめ。

https://qiita.com/mr_noppo/items/89506571174dfbcd889c

# 使用したものや事前準備
・Macbook Pro
・Visual Studio Code

# 主に参考にさせていただいた記事
https://ja.react.dev/learn/referencing-values-with-refs

# refとは
再レンダリングのトリガーにはしたくないが、レンダリング間で値を保持したい時に使用する。

## コンポーネントにrefを追加
refはcurrentプロパティを読み書きできるだけのプレーンなJavaScriptオブジェクト
```react
import { useRef } from 'react';

export default function Counter() {
  // 初期化
  let ref = useRef(0);

  function handleClick() {
    // 更新用関数のようにcurrentで現在の値を取得する
    ref.current = ref.current + 1;
    alert('You clicked ' + ref.current + ' times!');
  }

  return (
    <button onClick={handleClick}>
      Click me!
      {ref.current} {/*ここで表示してもレンダリング起きないため初期値である*/}
    </button>
  );
}
```

## refの使い方
```react
import { useState, useRef } from 'react';

export default function Stopwatch() {
  const [startTime, setStartTime] = useState(null);
  const [now, setNow] = useState(null);
  // インターバルIDをレンダリング間で保持するためrefにする
  const intervalRef = useRef(null);

  function handleStart() {
    // 時間部分の差分を出すため
    setStartTime(Date.now());
    // インターバル時間
    setNow(Date.now());

    clearInterval(intervalRef.current);
    intervalRef.current = setInterval(() => {
      setNow(Date.now());
    }, 10);
  }

  function handleStop() {
    // setIntervalの動作を取り消す
    clearInterval(intervalRef.current);
  }

  // レンダリングでstateの値を参照するためletで対応できる
  let secondsPassed = 0;
  if (startTime != null && now != null) {
    secondsPassed = (now - startTime) / 1000;
  }

  return (
    <>
      <h1>Time passed: {secondsPassed.toFixed(3)}</h1>
      <button onClick={handleStart}>
        Start
      </button>
      <button onClick={handleStop}>
        Stop
      </button>
    </>
  );
}

```

## refを使うタイミング
主にコンポーネントの外観に影響を与えないブラウザAPI
コンポーネントが値を保存する必要があるがそれがレンダーロジックに影響しない時、使用するため使う時は稀である。

## refを使用するときの原則
・refを非難ハッチとして扱う。頻繁に使うものではない。
・レンダリング中にref.currentを読み書きしない。

## 最後に
refを使う具体例を見つけていきたいと思いました。

# 次
https://qiita.com/mr_noppo/items/131fd4aaf702a8fb1051