OmniAICreator/Qiita-1.07M huggingface dataset:
ChatGPT（生成系AI）の業務利用ガイドライン記事まとめ

こんにちは。素晴らしい唐揚げです。

最近徐々に、会社単位での導入を行うところが増えてきたように思います。
また、社内利用ガイドラインを公開してくださるところもちらほら出てきていて、大変ありがたいなと感じています。
利用のため、リストがあったら嬉しいなと思ったので、作成します。

随時更新予定です。
もし、「私も作りました！」という方いらっしゃったら、ご連絡いただければ追加いたします。

ガイドライン：
・「クラスメソッド社内のAIサービス利用のガイドラインを策定しました」
https://dev.classmethod.jp/articles/guideline-for-use-of-ai-services/

・「業務でChatGPT等のAIを利用する際のガイドラインを考えてみる ＆ ガイドラインまとめ」
https://note.com/_spaj_/n/n93f6bb1ff367

・「ITアニマル占いを開発しながら ChatGPT Plus の全社導入と利用ガイドラインを作文した | Offers Tech Blog」
https://zenn.dev/offers/articles/20230323-chatgpt-company-wide-adopt-and-guidelines

・「生成系 AI の業務利用ガイドラインを紹介します」
https://blog.zaim.co.jp/n/n641fc2e19933

・and more
【ServiceNow】Content Publishingでの機械翻訳③

前回（[リンク](https://qiita.com/kamitani_shiho/private/bd38e17b1f4032732f2b "Content Publishingでの機械翻訳②")）に引き続きContent Publishingでの機械翻訳についてお話します。

## コンテンツパブリッシング設定
前回設定した内容に基づき、コンテンツパブリッシングで機械翻訳を行ってみます。
### コンテンツパブリッシングとは？

Employee Centerで表示するコンテンツを作成する機能を指します。
表示する対象のユーザや表示期間を設定することも可能です。
例えば…
・条件に合致したユーザにのみ一定期間お知らせを表示する
・開発部門のユーザにのみタスクを表示する
などの利用法があります。

__※コンテンツパブリッシングを利用するにあたってはプラグインが必要です。__
プラグインは下記の手順でインストールします。
①エージェント画面で「プラグイン」画面を開き、下記のプラグインを検索
　　・Content Publishing (id: sn_cd)
![ダウンロード (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2603803/d7733b6c-3974-bb21-cf78-f4dc1ff6185d.png)
②バージョンを確認してインストール

機械翻訳は下記のコンテンツで利用可能です。
・ポータル
・ブロック
・To Doリスト
・通知

## 利用イメージ
それでは画面イメージとともに説明していきます。
自動翻訳する対象のコンテンツは下記です。今回は英語原文のコンテンツを利用します。
![画像1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2603803/477d794b-02e7-5c63-0f0c-dc38af4b9102.png)
翻訳は下記の手順で実施します。
①設定から日本語表示に切り替え
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2603803/d979b5ca-5786-2470-b61d-68693cb63a4f.png)
②翻訳するコンテンツのレコードを開く
③右上の「コンテンツを翻訳」ボタンを押下
![画像2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2603803/e35e5b94-63a9-cb90-619d-8dcaa5530d80.png)
③翻訳先の言語を選択する
![キャプチャ2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2603803/17c755f5-c105-f0bf-b221-6f3c0fbfdfd5.png)
④コンテンツが自動翻訳され公開される
![画像3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2603803/74262fb2-9df2-fb15-f4ab-9316e47ebbee.png)
![画像4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2603803/cd4b457f-a305-0e88-5d9c-9008c1817e6b.png)
※ローカリゼーションフレームワークの設定で翻訳、公開に承認プロセスを指定することも可能です。
　設定については（[前回の記事](https://qiita.com/kamitani_shiho/private/bd38e17b1f4032732f2b "Content Publishingでの機械翻訳②")）をご参照ください

## まとめ
機械翻訳を活用することでよりスピーディかつ効率的にコンテンツを提供することが可能となります。
皆様、ぜひご活用ください！
GCEでコンテナからGPUを使いたい。

Google Compute Engine でGPUを使うコンテナアプリケーションを動かそうとしてハマったので記録しておく。

GCEにはcontainer optimzed os というコンテナを動かすときに使える軽量なイメージがあるらしい。
https://cloud.google.com/container-optimized-os/docs

しかしこのイメージはコンテナを動かすのに最低限必要なものしか入っていないようなので、nvidia-smi とかも入っていない。
COSイメージでGPUを動かすのに必要なGPUドライバをいいかんじにインストールしてくれるツールが存在するので、これを使う。

https://cloud.google.com/container-optimized-os/docs/how-to/run-gpus

```
$ sudo cos-extensions install gpu
```

とやると、必要なものがインストールされるらしい。[^cos_gpu_installer]

cos-optimized imageでGPUをセットしてVMインスタンスを起動する。ディスクは40GBあれば十分動いた。
起動したらsshする

とりあえずGPUがコンテナから見えているか確認する。nvidia/cuda のlatest タグは存在しないのでちゃんとバージョンを指定する必要がある。

```
$ docker run --rm --gpus all nvidia/cuda:11.0.3-base-ubuntu20.04 nvidia-smi -q
Unable to find image 'nvidia/cuda:11.0.3-base-ubuntu20.04' locally
11.0.3-base-ubuntu20.04: Pulling from nvidia/cuda
d7bfe07ed847: Pull complete 
75eccf561042: Pull complete 
191419884744: Pull complete 
a17a942db7e1: Pull complete 
16156c70987f: Pull complete 
Digest: sha256:57455121f3393b7ed9e5a0bc2b046f57ee7187ea9ec562a7d17bf8c97174040d
Status: Downloaded newer image for nvidia/cuda:11.0.3-base-ubuntu20.04
docker: Error response from daemon: could not select device driver "" with capabilities: [[gpu]].
ERRO[0007] error waiting for container: context canceled 
```

見えていない。GPUドライバをインストールする

```
$ sudo cos-extensions install gpu
```

インストールしたら、コンテナからGPUを認識できているか確認する。

```
$ docker run --rm --gpus all nvidia/cuda:11.0.3-base-ubuntu20.04 nvidia-smi -q
docker: Error response from daemon: could not select device driver "" with capabilities: [[gpu]].
ERRO[0007] error waiting for container: context canceled 
```

結果は同じ。なんでやねん。
調べると同じことにはまってる人がいた。

https://issuetracker.google.com/issues/164134488

このissueを追った限りでは、cos-extensions install gpu でいい感じにGPUドライバがインストールされてdocker run --gpus all とかやればGPUを認識できるようになってほしいところが、そうなっていなくて、下記のような感じでいろいろやらないと動くようになっていないみたいである。

```
#remount the driver folder as executable
sudo mount --bind /var/lib/nvidia /var/lib/nvidia 
sudo mount -o remount,exec /var/lib/nvidia 

docker run \
  --volume /var/lib/nvidia/lib64:/usr/local/nvidia/lib64 \
  --volume /var/lib/nvidia/bin:/usr/local/nvidia/bin \
  --device /dev/nvidia0:/dev/nvidia0 \
  --device /dev/nvidia-uvm:/dev/nvidia-uvm \
  --device /dev/nvidiactl:/dev/nvidiactl \
  nvidia/cuda:11.0.3-base-ubuntu20.04 nvidia-smi -q
```

先人のおかげで、とりあえずコンテナからGPUを認識できるようなった。公式の対応してほしいが、現状対応される気配はなさそうである。
あとは上記設定をスタートアップスクリプトとして設定してしまえば、あとは特に気にすることなく動かすことができそうである。


[^cos_gpu_installer]: [ソースコードの中身](https://cos.googlesource.com/cos/tools/+/refs/heads/master/src/cmd/cos_gpu_installer)はこのあたりにおいてある。
【Swift】オプショナル型とアンラップ

# はじめに
Swiftでは、変数の宣言時になにも値がない状態を許すか許さないかを、データ型で指定する必要がある。オプショナル型はデータ型のひとつ。

# オプショナル型とは
値がない状態を許すデータ型が「オプショナル型」で、変数宣言時のデータ型のあとに「？」か「！」を指定する。
「？」か「！」を付けない宣言は、値がない状態を許さない「非オプショナル型」になる。
一般的なオプショナル型は「？」を利用する。
オプショナル型は、変数の宣言と同時に自動で「nil」が代入される。
通常の変数（非オプショナル型）は、変数にnilを代入すると「nil cannot be assigned to type」のエラーとなる。
「？」で宣言したオプショナル変数を利用する場合には、アンラップが必要。
「！」で宣言したオプショナル変数を利用する場合には、アンラップをしなくても使用することができるが、開発者が値を保証する必要がある。

# アンラップとは
オプショナル型の変数やメソッドを、安全に取り扱う手法を「アンラップ」という。
アンラップは値がないこと「nil」をチェックして使う方法とチェックせずに使う方法がある。
チェックして使う方法は、「if let ~」「guard let ~」を利用する。
チェックせずに使う方法は、強制アンラップといい「！」を記述する。
強制アンラップは、開発者が値があると分かっているときに使う。

# オプショナル型の使い方
オプショナルは先述したとおり「nil」を代入できるため、オプショナルで宣言した変数が「nil」であっても参照できる。
```swift
// オプショナル型の宣言

var hoge: String?
var fuga: Int!

print(hoge)  // 実行結果 => nil
print(fuga)  // 実行結果 => nil
```

非オプショナル型の場合は、変数の値にnilを代入するとエラーが発生する。
```swift
// 非オプショナル型の宣言
var name: String
name = nil   //  実行結果 => エラー（nil cannot be assigned to type ~）
```

オプショナル型と非オプショナル型は同じように変数の操作をすることができない。
```swift
var num1: Int = 1
var num2: Int? = 2

print(num1 + 1); // 2
print(num2 + 1); // エラー（value of optional type 'Int?' not unwrapped; did you mean to use '!' or ‘?’?）
```
オプショナル型の変数の値がnilでないことを明示するためにアンラップする必要がある。
アンラップするためには、オプショナル型の変数の後ろに「！」を付ける。
```swift
// オプショナル型を宣言
var num: Int?
num = 100

print("num：\(num!)")  // 実行結果 => num：100
```

上記のように「!」でアンラップすれば安全に値を参照することができる。
オプショナル型の変数の値が「nil」の場合は、アンラップするとエラーになるので注意が必要。

# オプショナル型を比較

オプショナル型を用いて比較することをバインディング（Binding）という。
```swift
//オプショナル型の宣言
var num: Int?

//Binding
if let sum = num {
print("sum：\(sum)")
} else {
print("値が設定されていません。")  // 実行結果 ⇒ 値が設定されていません。
}
```

# 暗黙的なオプショナル型

オプショナル型は宣言時に型の後ろに「?」を付けるが、
暗黙的なオプショナル型を宣言するときには、型の後ろに「！」を付ける。
オプショナルを暗黙的に宣言すると、使用時にアンラップする必要がない。
そのため、初期値はnilでも使うときには値が格納されていることがわかっているときには、
暗黙的なオプショナル型を宣言したほうが安全。
しかし、暗黙的なオプショナル型でも値がnilでアンラップが必要なときに、
そのまま使用するとエラーになるので注意。
```swift
//暗黙的なオプショナル型の宣言

var num: Int!
print(num) // null

num = 100
print(num) // 100

num = nil
print(num + 10) // エラー
```

# まとめ

Swiftを使うならオプショナル型は、かなり必須な知識だと思った。

調べていて最初の壁のように感じたが、開発する上でほぼ必ず使う知識になるので、

使っているうちに理解できていくものだと思った。

実際にコードを書く際に使用し、理解を深めていきたい。
VSCodeのツリービューに更新ボタンを配置する方法

VSCode拡張機能を開発する時、ツリービューを実装するケースがあると思います。

その際に、ツリービューのタイトルの右端に、更新ボタンのようなアイコンを配置して、それがクリックされたタイミングで特定のコマンドが実行されるようにしたい場合、次のように`contributes`フィールドを設定します。

```package.json
"contributes": {
  "views": {
    "explorer": [
      {
        "id": "sampleTreeView",
        "name": "Sample Tree View"
      }
    ]
  },
  "commands": [
    {
      "command": "sampleTreeView.refresh",
      "title": "Refresh",
      "icon": {
        "light": "resources/light/refresh.svg",
        "dark": "resources/dark/refresh.svg"
      }
    },
  ],
  "menus": {
    "view/title": [
      {
        "command": "sampleTreeView.refresh",
        "when": "view == sampleTreeView",
        "group": "navigation"
      }
    ]
  }
}
```

タイトルの右端にアイコンを表示したいので、`view/title`キーを使って設定します。もし、ツリービューに並んでいる各要素を右クリックした際に、特定のコマンドのタイトルをコンテキストメニューのフォーマットに沿って表示したい場合は、`view/item/context`キーを使います。

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577119/6d22b678-7361-a6c8-0cdd-db670531d786.png)

もし、`...`の中にコマンドの存在感を隠したい場合は、`group`に`navigation`を指定するのではなく、`inline`を設定します。

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577119/8256c3bf-1e8d-7d89-3f96-1552851125e9.png)

https://code.visualstudio.com/api/extension-guides/tree-view#view-actions
VaultでDBクレデンシャルを使う方法



## DBクレデンシャル
### まずは現状確認
```
vault secrets list
```

### database シークレットを追加

```
vault secrets enable -path=lob_a/workshop/database database
```

### MySQLのDBの接続情報を設定

内容はこんなもの
dbname:mysqldatabase
username:hogehoge
password:fugafuga
```
# DB接続情報の設定 mysqldatabase というDBの場合、ここではapp,app-log2つのroleを許可しています。
vault write lob_a/workshop/database/config/mysqldatabase \
  plugin_name=mysql-database-plugin \
  connection_url="{{username}}:{{password}}@tcp(localhost:3306)/" \
  allowed_roles="app","app-long" \
  username="hogehoge" password="fugafuga"

# DB接続情報設定の確認
vault read lob_a/workshop/database/config/mysqldatabase -format=json

# DBログイン確認
mysql -u hogehoge -phugahuga

# 設定したrootパスを変更しておきましょう
vault write -force lob_a/workshop/database/rotate-root/mysqldatabase
→以降↑のrootパスは使えない
```

### DB接続用の Vault のroleの作成
```
vault write lob_a/workshop/database/roles/app-long \
  db_name=mysqldatabase \
  creation_statements="CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}';GRANT ALL ON my_app.* TO '{{name}}'@'%';" \
  default_ttl="1h" max_ttl="24h"
```
ちなみに、
TTLが終了すると、Vault は MySQL データベースからクレデンシャル情報を削除します。TTLの延長は、まだ到達していない場合にのみ機能します。
また、max_ttl パラメータで指定された期間を超えて延長することはできません。


### roleに紐づくクレデンシャルを生成
```
# VaultAPIでapp-longというroleに対してクレデンシャルを生成
curl --header "X-Vault-Token: root" "http://localhost:8200/v1/lob_a/workshop/database/creds/app-long" | jq .
# vault コマンドの場合こちら
vault read lob_a/workshop/database/creds/app-long

# 生成された(表示された)クレデンシャルでログイン 
# ↑で表示された<username><password>代入
mysql -u <username> -p<password>

# クレデンシャル情報の更新 たとえばTTLを2400秒へ 
# ↑で表示された<lease_id>代入
vault write sys/leases/renew lease_id="<lease_id>" increment="2400"

# 延長されていること
vault write sys/leases/lookup lease_id="<lease_id>"


```


### クレデンシャルを破棄
```
vault write sys/leases/revoke lease_id="<lease_id>"
```
【PHP】相対パス(相対URL)を絶対URLに変換する

自前で半端な実装をするより、優れたライブラリを使いましょう。
例えば、[Composer](https://getcomposer.org/) でインストールできる [guzzlehttp/psr7](https://github.com/guzzle/psr7) があります。
```sh
composer require guzzlehttp/psr7
```

インストールしたら、[GuzzleHttp\Psr7\UriResolver::resolve](https://github.com/guzzle/psr7#guzzlehttppsr7uriresolverresolve) で変換できます。
直接文字列を渡すことはできないので、GuzzleHttp\Psr7\Uri の形で渡します。
```php
require_once 'vendor/autoload.php';

$base_uri = new GuzzleHttp\Psr7\Uri('http://example.com/');
$relative_uri = new GuzzleHttp\Psr7\Uri('sample.php');
$absolute_uri = GuzzleHttp\Psr7\UriResolver::resolve($base_uri, $relative_uri);
echo $absolute_uri; // http://example.com/sample.php
```

結構奇っ怪なURLでもなんとかしてくれます。
```php
$base_uri = new GuzzleHttp\Psr7\Uri('http://user:pass@example.com/base/path/here/index.php?p=q');
$relative_uri = new GuzzleHttp\Psr7\Uri('.././/new/../././rel5.html');
$absolute_uri = GuzzleHttp\Psr7\UriResolver::resolve($base_uri, $relative_uri);
echo $absolute_uri; // http://user:pass@example.com/base/path//rel5.html
```

[GuzzleHttp\Psr7\UriResolver::relativize](https://github.com/guzzle/psr7#guzzlehttppsr7uriresolverrelativize) が逆関数(絶対URL→相対パス)となります。
```php
$base_uri = new GuzzleHttp\Psr7\Uri('http://example.com/');
$absolute_uri = new GuzzleHttp\Psr7\Uri('http://example.com/sample.php');
$relative_uri = GuzzleHttp\Psr7\UriResolver::relativize($base_uri, $absolute_uri);
echo $relative_uri; // sample.php
```

relativize はシンプルな相対パスを導出するので、元の相対URLと一言一句一致するわけではありません。
```php
$base_uri = new GuzzleHttp\Psr7\Uri('http://user:pass@example.com/base/path/here/index.php?p=q');
$relative_uri = new GuzzleHttp\Psr7\Uri('.././/new/../././rel5.html');
$absolute_uri = GuzzleHttp\Psr7\UriResolver::resolve($base_uri, $relative_uri);

$new_relative_uri = GuzzleHttp\Psr7\UriResolver::relativize($base_uri, $absolute_uri);
echo $new_relative_uri; // ..//rel5.html
```

今回のサンプルコード：https://github.com/mifumi323/php-relative-url-sample
動作確認環境：PHP 8.2.4、guzzlehttp/psr7 2.4.4
postgresql の index の解析メモ

postgresql の index メモです。
index を張ったときに、その index が有効かを確認するために、プランを確認することがあります。
どのようなログが出たらどうすればよいのか、ChatGPTに聞いてみました。
ChatGPTのアカウントがない方の参考にどうぞ。

◇ 質問
postgresql の index の実行計画をexplain analyze で見る場合に、遅い場合や削除したほうが良いindexの場合のログを教えてください。

◇ ChatGPTの回答
PostgreSQLでインデックスの実行計画を調べる場合、"EXPLAIN ANALYZE"コマンドを使用することができます。以下に、インデックスが遅い場合や削除したほうが良い場合に出力されるログの例を示します。
●インデックスが遅い場合のログ例

    QUERY PLAN

    Index Only Scan using idx_name on table_name (cost=0.43..8.45 rows=1 width=34) (actual time=0.014..0.015 rows=1 loops=1)
    Index Cond: (name = 'example'::text)
    Heap Fetches: 1
    Planning time: 0.106 ms
    Execution time: 0.031 ms

"Index Only Scan"に対して、"cost"や"actual time"が高い場合は、インデックスが遅いことを示しています。
この場合、インデックスを再作成するか、適切なインデックスを作成することで、クエリの実行を高速化することができます。

●削除したほうが良いindexの場合のログ例
    QUERY PLAN

    Seq Scan on table_name (cost=0.00..5558.80 rows=50000 width=10) (actual time=40.782..215.912 rows=50000 loops=1)
    Filter: (col1 = 1)
    Rows Removed by Filter: 500000
    Planning time: 0.086 ms
    Execution time: 326.343 ms

"Seq Scan"に対して、"cost"が低く、"Filter"がかかっている場合は、インデックスが効果的でないことを示しています。
この場合、インデックスを削除することで、クエリの実行を高速化することができます。ただし、必要な場合に備えて、インデックスのバックアップを作成することをお勧めします。

◇ 他にも知りたいので、ほかの explain analyze のログも教えてください。

PostgreSQLでインデックスの実行計画を調べる場合、"EXPLAIN ANALYZE"コマンドを使用することができます。以下に、他のログ例を示します。

    インデックスを使用したクエリのログ例
    QUERY PLAN

    Index Scan using idx_col1_col2 on table_name (cost=0.43..8.45 rows=1 width=34) (actual time=0.014..0.015 rows=1 loops=1)
    Index Cond: ((col1 = 1) AND (col2 = 'example'::text))
    Planning time: 0.106 ms
    Execution time: 0.031 ms

"Index Scan"に対して、"cost"や"actual time"が低い場合は、インデックスが効果的であることを示しています。

    クエリの実行計画に複数のインデックスが使用される場合のログ例
    QUERY PLAN

    Hash Join (cost=20.17..57.11 rows=2 width=12) (actual time=1.059..1.069 rows=1 loops=1)
    Hash Cond: (table1.col1 = table2.col1)
    -> Bitmap Heap Scan on table1 (cost=10.03..30.25 rows=2 width=8) (actual time=0.518..0.524 rows=1 loops=1)
    Recheck Cond: (col2 = 'example'::text)
    Heap Blocks: exact=1
    -> Bitmap Index Scan on idx_table1_col2 (cost=0.00..10.03 rows=2 width=0) (actual time=0.332..0.332 rows=1 loops=1)
    Index Cond: (col2 = 'example'::text)
    -> Hash (cost=10.10..10.10 rows=6 width=8) (actual time=0.521..0.521 rows=6 loops=1)
    Buckets: 1024 Batches: 1 Memory Usage: 9kB
    -> Index Scan using idx_table2_col1 on table2 (cost=0.28..10.10 rows=6 width=8) (actual time=0.048..0.505 rows=6 loops=1)
    Planning time: 0.132 ms
    Execution time: 1.105 ms

複数のインデックスが使用される場合は、複数の"Index Scan"や"Bitmap Index Scan"が現れます。
"Hash Join"のコストが高くなる場合は、インデックスを改善することで、クエリの実行を高速化することができます。

PostgreSQLでインデックスが存在しない場合のクエリ実行のログ例は、以下のようになります。
QUERY PLAN

Seq Scan on table_name (cost=0.00..20.00 rows=1 width=34) (actual time=0.050..0.055 rows=1 loops=1)
Filter: ((col1 = 1) AND (col2 = 'example'::text))
Rows Removed by Filter: 9999
Planning time: 0.052 ms
Execution time: 0.068 ms

"Seq Scan"によって、テーブルの全ての行をスキャンしていることがわかります。
"cost"は0.00から20.00の範囲になっており、インデックスがない場合はテーブルの全ての行をスキャンするため、コストが高くなります。
インデックスが存在しない場合、パフォーマンスが低下する可能性があるため、インデックスを適切に設定することが重要です。
クラスとインスタンスについての覚書　(JavaScript)

## ■クラスとは
オブジェクトを作成するための設計図のようなものです。クラスは、オブジェクトの特性（属性）や機能（メソッド）を定義します。クラス自体はオブジェクトではありませんが、オブジェクトを作成するためのテンプレートのようなものです。

## ■インスタンスとは
クラスから作成されたオブジェクトのことです。インスタンスは、クラスで定義された属性とメソッドを持ちます。クラスから作成された複数のインスタンスは、それぞれ独自の属性を持ちます。
#

- JavaScriptでは、クラスとインスタンスは以下のように定義されます。

クラスの定義:

```javascript
class MyClass {
  constructor(param1, param2) {
    this.property1 = param1;
    this.property2 = param2;
  }

  myMethod() {
    console.log("Hello World!");
  }
}
```

上記のコードでは、`MyClass`という名前のクラスを定義しています。constructor関数は、クラスをインスタンス化する際に呼び出され、新しいインスタンスにプロパティを追加します。`myMethod()`は、クラスに属するメソッドを定義します。

インスタンスの生成:

```javascript
const myinstance = new MyClass("価値1", "価値2");
```

上記のコードでは、`MyClass`クラスから`myInstance`という名前のインスタンスを作成しています。constructor関数の引数は、プロパティに渡されます。

インスタンスのプロパティやメソッドの呼び出し:

```javascript
console.log(myInstance.property1); // "価値1"
console.log(myInstance.property2); // "価値2"
myInstance.myMethod(); // "Hello World!"

```
上記のコードでは、`myinstance`というインスタンスのプロパティとメソッドにアクセスしています。`property1`と`property2`は、constructor関数で定義されたプロパティです。`myMethod()`は、クラスに属するメソッドです。

※クラスは大文字、インスタンスは小文字から定義するのが通例です


## ※constructor関数について
constructor関数は、JavaScriptにおいて、クラスを定義するための特別なメソッドの一つです。この関数は、クラスがインスタンス化されたときに実行され、インスタンスに初期値を与えるために使用されます。
# 
以下は、constructor関数を使用してクラスを定義し、インスタンスを生成する例です。

```javascript
// Rectangleクラスを定義する
class Rectangle {
  // コンストラクタ関数を定義する
  constructor(width, height) {
    this.width = width;
    this.height = height;
  }

  // 面積を計算するメソッドを定義する
  getArea() {
    return this.width * this.height;
  }
}

// Rectangleクラスからインスタンスを生成する
const rect = new Rectangle(10, 20);

// 面積を出力する
console.log(rect.getArea()); // 結果: 200

```

上記の例では、`Rectangle`クラスを定義しています。このクラスには、constructor関数が定義されています。この関数は、`width`と`height`の2つの引数を受け取り、それらを使用してインスタンスに`width`と`height`の値を設定します。また、`Rectangle`クラスには、`getArea`メソッドがあり、このメソッドはインスタンスの`width`と`height`の値を使用して、面積を計算します。

次に、newキーワードを使用して、`Rectangle`クラスから`rect`という名前のインスタンスを生成します。これにより、`width`が10、`height`が20の新しい`Rectangle`オブジェクトが作成されます。

最後に、インスタンスの`getArea`メソッドを呼び出して、面積を出力します。

constructor関数は、クラス内に初期化処理を書くための便利な方法です。
この関数を使用することで、インスタンスを生成するたびに同じ初期化処理を書く必要がなくなり、コードを簡潔に保つことができます。
また、constructor関数は、クラスを継承する際にも重要な役割を果たします。継承したクラスでも、親クラスのconstructor関数を呼び出すことで、親クラスと同じ初期化処理を実行することができます。
Next.js で path 要素の stroke-linecap 属性を設定すると warning がでる

Next.js 13 で path の属性に `stroke-linecap`　を指定したら、warning がでた。

- 参考: [Some SVGs work in Nextjs and some not, why?](https://stackoverflow.com/questions/71027651/some-svgs-work-in-nextjs-and-some-not-why)

## ソースコード

```javascript
<svg className="w-2.5 h-2.5 text-pink-200" width="16" height="16" viewBox="0 0 16 16" fill="none">
    <path d="M5.27921 2L10.9257 7.64645C11.1209 7.84171 11.1209 8.15829 10.9257 8.35355L5.27921 14" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
</svg>
```

## warning の内容

```zsh
Warning: Invalid DOM property `stroke-width`. Did you mean `strokeWidth`?

...

    at Body (/Users/centipede/works/sample-project/node_modules/next/dist/server/render.js:620:21)
Warning: Invalid DOM property `stroke-linecap`. Did you mean `strokeLinecap`?
```

## 解決策
svg 要素に `xmlns="http://www.w3.org/2000/svg"` 属性を追加すれば、warning は表示されなくなる。

```javascript
<svg xmlns="http://www.w3.org/2000/svg" className="w-2.5 h-2.5 text-pink-200" width="16" height="16" viewBox="0 0 16 16" fill="none">
```
スクラムでエンジニアがデザインをして分かった、4つのアンチパターン

以前関わっていたエンジニア10名程のスクラムチームで、**デザインをエンジニア自身でやりつつ進めていくこと**をやってみたのですが、そこから分かった4つのアンチパターンを書きます。

- iOS/Androidのネイティブアプリをやっている
- デザイン=画面デザイン+画面仕様
- 使っているデザインツールはFigma
- デザインに関しては全員浅い経験

なお、最近のスクラムでデザインを取り入れるにあたって、デュアルトラックアジャイルのような手法（というか考え方？）が生まれつつあり、私自身がこの記事に書いたことに取り組んでいたときにはその存在を知りませんでした。なので、あくまで現場でもがいてみた記録として見ていただけると幸いです。

- [デュアルトラックアジャイルって結局何なの？｜かわきん（ちゃんかわ）/atama plus スクラムマスター](https://note.com/chankawa919/n/n093b48118b1c)

### 1. 片手間でデザインをやる

最初、エンジニアがデザインをスクラムの中でやることで、

- ちゃんと見積もりを付けてスプリントの中でうまいこと回せる
- エンジニア自身が考えた、実装しやすいデザインになる（かも）

と思っていました。

しかし実際には開発に追われる中でデザインをこなすことはなかなかに厳しく、特に全員が開発・デザイン両方をこなしていたので、デザインを片手間でやっている状況でした。

当然割ける時間が少ないので、細かい部分についての議論はなかなか出来ず、あくまで機能を実現するためのデザインの話にフォーカスしてしまいます。それはもちろん重要な事なのですが、全体的なデザインの統一感や細かい部分の使い勝手にまで議論の時間が回せず、良くないなと感じていました。また議論をしたとしても、結局全員デザインの経験が非常に浅いので、これが良い！っていう決定的な結論をくだせず、ずるずると議論が長引いて打ち切る事で仕様が決まるということがままありました。

片手間でデザインをやるのではなく、ちゃんと専任のデザインについて責任を持つ人が必要だな…と感じました。

### 2. デザインのタスクと、開発のタスクの見積もりを共通化する

スクラムのスプリントでタスクをこなすには、基本的には見積もりが必要だと思っています。エンジニアがデザインと開発両方を担うようにしていたため、見積もりを共通化していました。

開発には開発のリファレンスストーリーがあり、そこにストーリーポイントが付いています。デザインにはデザインのリファレンスストーリーがあり、そこにポイントがついています。

そこを共通化するには時間ベースで換算するしかありません。しかし、スクラム開発ではベロシティは変動します。つまり、開発のストーリーポイントが実際にどのくらい時間に換算できるかは常に変わっていきます。そこを常にデザインのポイントと同期しなければいけないわけですが、これはもうめちゃくちゃ面倒くさいですよね。

デザインのタスクに開発と同じ基準の見積もりを付けてスプリントに入れるのは個人的には良くない方法だと思っています。

### 3. PRのフローをなぞって、デザインのレビューもフローに落とし込もうとする

多くのソフトウェアエンジニアは、GitHubのPullRequestを用いた開発サイクルに慣れ親しんでいますよね。なので、デザインもそのフローに落とし込んでみようとしたのですが、罠がありました。

#### レビューがクッソ大変

Figmaを使っていたのですが、Figmaにはレビュー機能がありません。（最上位のプランならレビュー機能がありますが、めちゃくちゃ高いです）

ではどうしたかというと、Figma上でレビューのステータス（Approveしているか）を表示するコンポーネントを作って、変更箇所にぺたぺた貼り、Figma上で依頼を出してレビュー→コメント→修正→再レビューのサイクルを回していました。これが非常に大変でした。あるフィーチャーにまつわる画面を同時多発的に編集すると、どこをどういじったのかを理解するのがかなり難解になり、また仕様の部分のレビューも行っていたので、そこのやり取りも含めて兎に角コミュニケーションの手間が半端無い状況になっていました。

結果、フローはやめて皆で画面を見ながら会話でレビュー的なものを行うのが最も容易いという結論に至りました。

### 4. ガチガチにデザインを組もうとする

ソフトウェアエンジニアたるものコンポーネントの再利用性を意識して綺麗にFigmaの画面を組みたいですよね。Figmaの操作を理解してくると色々ガッチリ組みたくなるし、そのほうが後々プロトタイプとしても良いだろうという事で最初はガッチリやってました。

これは罠です。

綺麗に作ろうとすればするほどメンテのコストが跳ね上がっていき、途中で破綻するとそこで諦めるようになります。途中で諦めるのであれば、最初からそんなガッチリやらなくて良いわけです。Figmaもコンポーネントのインスタンスにコンポーネント入れ子にする事が出来なかったり、ソフトウェアエンジニア的な思考で階層構造を組む事が出来ないようになっています。

デザインの専任の人がいれば、徹底的にFigmaのデザインの組み方をリファクタリングして維持していけると思うのですが、最初にも述べた通り我々は片手間でやっていたのでその時間を捻出するのも難しく、そうそうに破綻してしまったのでした。

## 最後に

実はこの記事は前職の会社でのプロジェクトの話を書いたものです。今はもう離れてしまったので、その後チームでのデザインのフローがどうなったのかは全く知らないのですが、チームでもがいていた当時自分がどう考えていたかを整理するために記事を書きました。スクラム×デザインはまだまだフロンティアな領域だと思うので、またチャレンジする機会があればもがいてみようと思っています。ありがとうございました。
Unixコマンドライン操作【基礎編③】

コマンドラインの基礎知識について1から復習中なので、
主に自分の備忘のために学んだことを記録しておこうと思います。のその③

教材はRuby on Railsチュートリアルのコマンドライン編です。
第4章の「ファイルを調べる」の内容について書こうと思います。
3章以降は有料コンテンツのため、覚えたコマンドだけ簡単に紹介します

macOSを使っています。
# 1.ファイルのダウンロード

```Bash:ターミナル
$ curl -OL example.com/foo.txt
```
**詳しいことはあまり書かれていませんでしたが**
とにかくcurlを使えば指定したURLに対していろいろ操作できるようです。
一旦そういうものだとだけ覚えておくことにします。

とりあえず、オプション -OL を指定すればURL上のファイルをダウンロードできました。

###### おまけ
「which」・・指定したコマンドが使用可能かどうかを確認するためのコマンド

```Bash:ターミナル
$  which curl 
```
実行後特に何も表示されなければ、そのコマンドは使える状態にないということなので
別途対応が必要になります。

###### その他コマンドラインで役に立つ技


```Bash:ターミナル
$  !!    ← 直前に実行したコマンドの再実行
$  !curl ←  最後に実行した（！の後に書いた）コマンドの再実行
```
また、^R(コントロール+R)を使うと
コマンド履歴を検索して、さらに必要な部分は修正してから実行できます。

# 2.ファイルの冒頭や末尾を取り出す
```Bash:ターミナル
$  head foo.txt    ←  ファイルの最初の10行を取り出す
$  tail foo.txt    ←  ファイルの末尾の10行を取り出す
```

### ワードカウントとパイプ

「wc」・・ファイルが全部で何行あるのか調べるコマンド

```Bash:ターミナル
$  wc foo.txt
2620  17670  95635 foo.txt
```

実行結果の左から「行数」「単語数」「バイト数」

「パイプ（|)」
```Bash:ターミナル
$  head foo.txt | wc
10 46 294
```
パイプ(|)の左側の実行結果を右側のコマンドの標準入力として使うイメージ
※用語の使い方とかが間違っていたらすみません

# 3.ファイルをより詳しく調べる

「less」・・ファイルをインタラクティブ（対話のよう）に表示
```Bash:ターミナル
$  less foo.txt
```

### less(やman)で使えるキー操作一覧

```B
上/下矢印キー    :1行戻る/進む	
スペース	     :1ページ進む	
⌃F	             :1ページ進む	
⌃B	             :1ページ戻る	
G	             :ファイルの末尾にジャンプ	
1G	             :ファイルの冒頭にジャンプ	
/<文字列>	     :文字列を検索	
   n	             :次の検索結果にジャンプ
   N	             :1つ前の検索結果にジャンプ
q	             :終了
```

## grep
.. ファイル内の文字列の検索に使用する
```Bash:ターミナル
$  grep <検索したい文字列> <ファイル名>
$  grep -i <検索したい文字列> <ファイル名>   ← 大文字小文字の区別なしで検索
```

実行結果には、検索したい文字列を含む行がすべて出力されます。

### プロセスのgrep(プロセスを止める方法も）
```Bash:ターミナル
$ ps aux  ← 自分のシステムのすべてのプロセスリストを表示
$ ps aux | grep <検索文字列>  ← 検索文字列を含むプロセスだけを表示
(例)ubuntu *12241* 0.3 0.5 589960 178416 ? Ssl Sep20 1:46
spring app | sample_app | started 7 hours ago
```
※ps auxの他には、topコマンドでシステムでリソースを最も消費しているプロセスを確認する方法もあるとのこと
この例で、**で囲った部分がプロセスID（12241)

このプロセスを終了させるには
```Bash:ターミナル
$ kill -15 <プロセスid>
```

こちらはidを一旦調べてから、プロセスを終了させる方法
もし名前のわかりきっているプロセスを終了させる場合は↓
```Bash:ターミナル
$ pkill -15 -f <name>
```

今回はこんなところで！

ありがとうございました。

※ようやくQiitaではMarkDownという書き方があることを知りました・・
【競プロ/Swift】まよコン 2023/03/28

# 注意事項
本記事は復習のための日記的なものであり、丁寧な解説を求めている方には不十分かと思われますので、ご了承のほどお願いいたします。

# 正解済み問題
## A - Repression
**問題文**
[こちら問題ページ](https://atcoder.jp/contests/abc207/tasks/abc207_a)

**解答**
ソートして後ろ二つを足し算。

```swift
let abc = readLine()!.split(separator: " ").map{Int($0)!}.sorted()
print(abc[1] + abc[2])
```
## B - Alcoholic
**問題文**
[こちら問題ページ](https://atcoder.jp/contests/abc189/tasks/abc189_b)

**解答**
浮動小数点による誤差でだいぶ時間使った。
基本的に整数にしてから、計算するようにした方が良い。

```swift
let nx = readLine()!.split(separator: " ")
let n: Int = Int(nx[0])!
var x: Int = Int(nx[1])! * 100

var totalMl: Int = 0
var counter = 0
for _ in 1...n {
    let vp = readLine()!.split(separator: " ").map{Int($0)!}
    let ml = vp[0] * vp[1]
    
    totalMl += ml
    counter += 1
    if x < totalMl {
        break
    }
}

if x < totalMl {
    print(counter)
} else {
    print(-1)
}
```
# 誤答及び、未解答問題
## D - Replacing
**問題文**
[こちら問題ページ](https://atcoder.jp/contests/abc171/tasks/abc171_d)

**誤答**
馬鹿正直にループ気にせず解いてみたが、案の定TLEで終了。
他の方法も考えてみたが、結局分からなかった。

```swift
let n = Int(readLine()!)!
var aArray = readLine()!.split(separator: " ").map{Int($0)!}
let q = Int(readLine()!)!

for _ in 0..<q {
    let bc = readLine()!.split(separator: " ").map{Int($0)!}
    aArray.replace(before: bc[0], after: bc[1])
    print(aArray.reduce(0, +))
}


extension Array where Element: Equatable {
    mutating func replace(before: Array.Element, after: Array.Element) {
        self = self.map { ($0 == before) ? after : $0 }
    }
}
```

**正答**
```swift
func readInts() -> [Int] {
    return readLine()!.split(separator: " ").map{ Int(String($0))! }
}

let n = Int(readLine()!)!
let a = readInts()
let q = Int(readLine()!)!

let m = 100000
var s = a.reduce(0, +)
var counter = [Int](repeating: 0, count: m + 1)
a.forEach{ counter[$0] += 1 }

for _ in 0..<q {
    let query = readInts()
    let b = query[0], c = query[1]

    let diff = (c - b) * counter[b]
    counter[c] += counter[b]
    counter[b] = 0

    s += diff
    print(s)
}
```

# 参考
https://kenkoooo.com/atcoder/#/contest/show/b3ec9024-0444-4b76-b4cd-56ca39070e93?activeTab=Problems
初学者によるDOMについて覚書

## DOMとは
DOM（Document Object Model）はWebページを表現するための仕組みで、Webページの構造や要素、属性、イベントなどを扱うことができます。

DOMは、JavaScriptなどのスクリプト言語を使用して、Webページの要素にアクセスしたり、Webページのコンテンツを動的に変更したりするために使用されます。JavaScriptは、DOMを使用して、Webページの要素にアクセスし、変更することができます。

※Document Object Model（DOM）は、Webページを表現するための標準化された方法です。DOMは、HTML、XML、SVGなどのドキュメントを、階層的なツリー構造で表現します。このツリー構造は、Webページの要素、属性、テキスト、および他のコンテンツを表します。

例えば、以下のようなHTMLコードがあったとします。

```html
<html>
<head>
	<title>DOMの例</title>
</head>
<body>
	<h1>DOMの例</h1>
	<p>DOMはWebページの要素を扱うための仕組みです。</p>
	<button id="myButton">ボタン</button>
</body>
</html>

```

このHTMLコードを解析すると、以下のようなDOMツリーが作成されます。

```markdown
- document
	- html
		- head
			- title
				- テキストノード："DOMの例"
		- body
			- h1
				- テキストノード："DOMの例"
			- p
				- テキストノード："DOMはWebページの要素を扱うための仕組みです。"
			- button
				- テキストノード："ボタン"

```

このDOMツリーを使って、JavaScriptなどのスクリプト言語を使って、Webページの要素にアクセスし、操作することができます。

例えば、以下のようなJavaScriptコードを書くことで、ボタンをクリックした時にアラートダイアログを表示することができます。

```javascript
// ボタン要素を取得する
var button = document.getElementById("myButton");

// ボタン要素にクリックイベントを追加する
button.addEventListener("click", function() {
    // アラートダイアログを表示する
    alert("ボタンがクリックされました！");
});

```

このように、DOMを使うことで、Webページの要素を動的に操作することができます。


## DOMでよく使われるメソッドやプロパティ
DOMは、Webページの要素にアクセスするための多くの方法があります。
以下に、DOMでよく使われるメソッドやプロパティをいくつか紹介します。

1. getElementById()
このメソッドは、id属性が指定された要素を取得するために使用されます。例えば、上記の例で使用したように、ボタン要素を取得するために使用できます。

```javascript
var button = document.getElementById("myButton");

```

1. querySelector()
このメソッドは、CSSセレクターを使用して、Webページ内の要素を取得するために使用されます。例えば、以下のように使用することができます。

```javascript
// ボタン要素を取得する
var button = document.querySelector("button");

// クラス名が"myClass"である要素を取得する
var elements = document.querySelectorAll(".myClass");

```

1. innerHTML
このプロパティは、指定された要素のHTMLコードを取得または設定するために使用されます。例えば、以下のように使用することができます。

```javascript

// ボタン要素のテキストを取得する
var buttonText = button.innerHTML;

// ボタン要素のテキストを変更する
button.innerHTML = "新しいボタン";

```

1. addEventListener()
このメソッドは、指定された要素にイベントリスナーを追加するために使用されます。例えば、以下のように使用することができます。

```javascript

// ボタン要素にクリックイベントを追加する
button.addEventListener("click", function() {
    // クリックされた時に実行される処理
});

```

以上が、DOMの基本的な情報です。
メモ：役に立つLinuxコマンド

## ファイルの行数を知りたい
```shell
wc -l ファイル名
```

## 一定時間ごとに特定の処理を動かしたい
```shell
while true ; do date; sleep 3 ; done
```

:::note
※（設定値にもよるかもしれないが）Broken Pipeにも勝てるので、接続切れ対策として使える。
:::

## 直近のコマンド実行履歴を見たい
```shell
history 数字（件数）
```

（例）history 10
直近の10件の履歴が出る。

## 実行したコマンド履歴を指定のワードで検索したい
```
history | grep ワード
```

## ファイルの最後から100行見たい
```shell
tail -n 100 ファイル名
```

## ファイルの最初から100行見たい
```shell
head -n 100 ファイル名
```

## 指定のワードが含まれる総行数を知りたい
```shell
grep ワード ファイル名 | wc -l 
```

## コンソール画面をきれいにしたい（クリア）
```shell
clear
```
または
```
ctrl + L
```

## ファイル内の文字数を取得したい
```shell
wc -m ファイル名
```

## 指定した行数以降を確認したい
```shell
less +行数 ファイル名
```

## cdする前のディレクトリに戻りたい
```shell
cd -
```

## ファイル内の検索結果に行番号を表示したい
```shell
grep -n 検索ワード ファイル名
```

## ファイル内を大文字と小文字を区別せず検索したい
```shell
grep -i 検索ワード ファイル名
```

## コマンドの実行時間を知りたい
```shell
time コマンド名
```

## コピー元と同じタイムスタンプでコピーしたい
```shell
cp -p コピー元ファイル　コピー先ファイル
```

:::note
※Windowsと違い、オプションをつけないと、cpした時間のタイムスタンプになります。
※pはパーミッションと所有者とタイムスタンプを保持するもので、preserveの意味です。
:::

## ディレクトリ配下を再帰的にコピーしたい
```
cp -r コピー元ディレクトリ コピー先ディレクトリ
```

:::note
※コピー先ディレクトリは予め作成しておかなくても大丈夫。
:::

## ディレクトリ配下を再帰的に削除したい
```shell
rm -r ディレクトリ
```

:::note
※rmdirは、ディレクトリ内が空でないとエラーになるため、ディレクトリ削除は基本的にrmコマンドを使う。
:::

## 直前に実行したコマンドの結果を知りたい
```shell
echo $?
```

:::note info
※作業ミスを防ぎたいときに使ったりする。0なら正常。
:::

## コマンドの出力結果が大量にあるので、非表示にしたい
```
コマンド > /dev/null
```

:::note
/dev/nullとは、入力元としても出力先としても何も表示されない特殊なファイルのこと。
:::

## メモリの使用状況をメガバイト単位で確認したい
```shell
free -m
```

## プロセスIDの最大値を確認したい（設定したい）
```shell
cat /proc/sys/kernel/pid_max
```

※初期値は32768

## メモリを消費しているプロセスを使用順にソートして表示したい
```shell
ps -aux --sort -%mem
```

※過去の経験でGNOME（/usr/bin/gnome-shell）が一番消費しているということがあった。結構メモリを食うんですね。

## swapしているプロセスの上位10個を表示
```shell
grep VmSwap /proc/*/status | sort -nr -k 2 | head -n 10
```

## 特定のポートを使っているプロセスを知りたい
```shell
lsof -i:8080
```

※オプションにコロンをつけないとエラーになる。

## 特定の処理を動かしているプロセスIDをkillしたい
PIDは、プロセスの起動のたびに流動的に変化するものなので、killするためには都度psコマンドで特定する必要がある。

具体的には、
ps -aux でPIDを特定
↓
kill 「PID」
となるが、これを一発で行うには以下。

```shell
ps -aux | grep "[-]jar sample.jar" | awk -F " " '{print "kill", $2}' | sh
```

※grepの対象に[]を入れているのは、grepを実行するとgrep自体も結果に含まれてしまうのを除外するため。詳しくは[psをgrepした結果からgrep自身を除外する方法](https://webkaru.net/linux/ps-grep-exclude/)を参照。

※ps -auxを実行すると、2番目の列がPIDになるため、$2とする。なお、-Fは区切り文字であり、今回の場合は半角スペースを指定している。

## historyに実行時間も表示されるようにしたい
下記を~/.bashrcに追記する（※単にコンソールで実行するだけでは、設定が永続化されない）。

```shell
export HISTTIMEFORMAT='%F %T '
```

## ローカルホストのIPアドレスを取得したい

```shell
echo `ifconfig | grep -m 1 inet | awk -F " " '{print $2}'`
```
ssh接続でgit pullやpushでのパスワード入力を省略したい

### はじめに
VsCodeからSSH経由でGitに接続。
git pullやpushでの毎回のパスワード入力を省略したくて試行した内容メモです。
### 本文
まずsshキーをssh-agentへ登録。
```
$ ssh-add /Users/user_name/.ssh/id_rsa
```
と思ったら失敗。communication with agent failedとのこと。
エージェントとの通信に失敗しました、つまりエージェントが起動してないってことでした。
```
Could not add identity "/home/webuser/.ssh/id_rsa": communication with agent failed
```
よってssh-agentを起動するコマンドを実施後に、ssh-addを再チャレンジ。
（ssh-agent -> sshの公開鍵認証を代行してくれる）
```
$ eval `ssh-agent`
$ ssh-add /Users/user_name/.ssh/id_rsa
```
成功！ ssh-add -lでキーの登録を確認できました。

しかしOSの再起動後にまたパスワードの要求が、、、
前回確認できたキーの登録も無し。
```
error fetching identities for protocol 1: communication with agent failed
error fetching identities for protocol 2: communication with agent failed
The agent has no identities.
```
どうやらシェルの再起動でssh-agentの情報はリセットされるらしい。

WindowsのPowerShellを管理者権限で起動し、ssh-agentの自動起動を設定してみる。
```
Set-Service ssh-agent -StartupType Automatic
Start-Service ssh-agent
Get-Service ssh-agent
```
上記コマンド実行後、再起動してもパスワードの入力を要求されなくなりました！

参考にさせていただいた記事
https://qiita.com/sshojiro/items/60982f06c1a0ba88c160
https://qiita.com/aisha/items/807fd2693dea77b1c695
https://qiita.com/fuji44/items/da63086c11c772c9f5fb
Mac ネイティブのbashからbrewでインストールしたbashに切り替える

# 概要

- Macに元から入っているbashからbrewでインストールしたbashに切り替える方法をまとめる。

# 方法

1. 下記コマンドを実行してネイティブのbashのバージョンを確認する。

    ```
    bash --version
    ```

1. 下記を実行して元から入っているbashのパスを確認する。

    ```
    cat /etc/shells
    ```

1. 下記を実行してbrewでbashをインストールする。

    ```
    brew install bash
    ```

1. Macを再起動する。
1. bashのバージョンを確認すると無事更新されていた。

    ```
    bash --version
    GNU bash, バージョン 5.2.15(1)-release (x86_64-apple-darwin22.1.0)
    ```
【ReactHooks】useEffectについて

## useEffectとは
Reactコンポーネント内で副作用を実行するためのフックです。副作用とは、API呼び出し、データの取得、DOMの更新、タイマーの設定、イベントリスナーの登録など、**コンポーネント自体のレンダリングには直接関係ないけど、アプリケーションに影響を与える処理**です。

`useEffect`は、第一引数に副作用として実行したい処理を、第二引数に依存配列を渡します。依存配列には副作用の実行に必要な変数を指定し、その配列内の変数が変更される度に副作用が実行されます。

```javascript
useEffect(() => {
  /* 第一引数に副作用として実行したい処理 */
  console.log('副作用が実行されました')
},[依存配列])
```

#### 実行されるタイミング
**1: マウント(初回ロード)された時** `componentDidMount`
**2: レンダリングされた時** `componentDidUpdate`
**3: アンマウントされた時** `componentWillUnmount`
<br>

以下、データ取得の場合の例です↓
```javascript
import React, { useState, useEffect } from "react";
import axios from "axios";

function App() {
  const [data, setData] = useState([]);

  useEffect(() => {
    const fetchData = async () => {
      const result = await axios("https://api.example.com/data");
      setData(result.data);
    };
    fetchData();
  }, []);

  return (
    <div>
      <ul>
        {data.map(item => (
          <li key={item.id}>{item.name}</li>
        ))}
      </ul>
    </div>
  );
}
```
`useEffect`を使用して非同期処理を実行し、取得したデータを`useState`を使ってコンポーネントの状態に保存しています。このように、データの取得をコンポーネントのレンダリングとは分離して実行できます。
<br>

他にも`state`の変更を監視して処理を実行します。
```javascript
useEffect(() => {
  if (count < 10) return;
  console.log('countが10以上です')
}, [count]);
```

## クリーンアップ関数
`useEffect`クリーンアップはフックの関数であり、コンポーネントが**アンマウントされる前に実行**されます。そうすることで、メモリリークを防ぎ、アプリケーションのパフォーマンスを最適化できます。

例えば、購読など「定期的に外部データを読み込みする」ようにしていると、放置したままでは、そのページから移動しても定期的な読み込みが生きたままです。それをクリーンアップ関数を使って、`useEffect`で設定した処理をアンマウント時に解除してあげます。

また、第二引数を空にすることでレンダリング毎に実行されますが、予期しないケースで`useEffect`が実行されてしまう可能性があるため、第2引数を空にすることはNGです。

第二引数の配列の中身を空にすると、**初回のレンダリング後のみ実行されます**。
```javascript
useEffect(() => {
  // 処理
}, [])
```
<br>

以下、クリーンアップ関数を使用した例です。
```javascript
const [ count, setCount ] = useState(0);

useEffect(
  () => {
    const time = setInterval( // １秒ごとに定期実行する関数を、最初のレンダリングのときにセット
      () => {
        console.log("１秒ごとに定期実行");
        setCount((prevState) => prevState + 1); 
      }, 1000
    );
    return () => clearInterval(time); //クリーンアップ関数。定期実行する関数をリセット
  }, 
  []
);

return (
  <div className = {styles.main}>
    <div>{count}</div>
  </div>
)
```
`useEffect`のクリーンアップ関数を設定しないと、ページ移動しても`setInterval`が実行され続け、メモリリークに繋がります。
メモ：hostsファイルとは

# hostsファイルとは？

ホスト名とIPアドレスの対応を書いておくファイル。
OSの設定ファイルのひとつ。

DNSサーバはドメイン名とIPアドレスを行うものであるが、hostsファイルはDNSよりも先に参照される。
※DNSが登場する以前に使われていた仕組みでもある。
※hostsファイルとは、ローカル環境だけのDNSとも言える。

# hostsファイルの格納場所
C:\Windows\System32\drivers\etc\hosts

windows+rで名前欄にdriversと打つと、該当フォルダを一発で開くことができる。

# 編集の仕方
管理者権限でテキストエディタ（メモ帳など）を起動させておき、ファイルを開く。

更新した場合、PCの再起動は不要で、即設定が適用される。
（しかし、今までに何回か、設定がなかなか適用されていないとしか思えない事象に遭ったことあり）

# 備考

同じホスト名について重複で記載がされている場合、上に書いてある方が適用される模様。

```
192.168.0.0.1 foo
127.0.0.1 foo
```
【備忘録】klipperのマクロ設定が沼過ぎる件(前編)

# 困っていること
3Dプリンタのファームウェアとして主流のMarlinに対して、KlipperはPC(ラズパイ等のシングルボードPC含む）の演算支援により、更に印刷速度・精度の向上や独自機能拡張が可能です。
一方、Marlinではネイティブに対応していたいくつかの機能（G29：オートレベリング）を、マクロによって各自実装する必要があります。ただでさえ高機能なKlipperなのに、マクロによって更に自由度が高くなるので、調べるのは大変です(日本語の情報も少ないですし）。そこで、どうやって調べればいいのか、マクロを書いたらいいのか、備忘録的にメモろうと思います。

# 情報源
## Marlin G-code
[Marlinが対応しているGコード](https://marlinfw.org/meta/gcode/)。まずは3Dプリンタで使われるGコードの動作を調べるのが大前提。Klipperで未対応のGコードはマクロを組む必要があります。

## Klipper公式サイト
- 信頼できる：★★★★★
- 情報量　　：~~★★★★★~~  ⇨ ★★★☆☆
- 銀の弾丸度：~~★☆☆☆☆~~  ⇨ ★★★☆☆
(銀の弾丸度＝直近の問題解決に直ぐ役に立つか)

まずは公式Documentsを読むのが前提でしょう。
- [G-Codes](https://www.klipper3d.org/G-Codes.html)
- [Status reference](https://www.klipper3d.org/Status_Reference.html)
    - Klipperマクロでは、ここに記載されているGコード(例:G1)や変数(例：printer.toolhead.axis_minimum.x)、特殊なコマンド（例：BED_MESH_CALIBRATE）、及びjinja2の構文を組み合わせます。
- [Commands templates](https://www.klipper3d.org/Command_Templates.html)
    - 一応公式でもマクロの書き方のチュートリアルが存在します。

流石公式と言ったところです。しっかり情報が載っていますが、 ~~実際の3Dプリンタで何を書いたら良いか、 **自分で考える** 必要があります。~~

【追記】
なんか見つけました。。。
[公式Github/config/sample-macros.cfg](https://github.com/Klipper3d/klipper/blob/master/config/sample-macros.cfg)
ここのマクロ例は実際のプリンタの実装に近く＆シンプル。
まずはここのマクロ例を読むと何を書くのか理解しやすいと思います。
 ~~(こんな良い例があるなら最初からリンク張って誘導しようよ。しかも公式サイトには説明の無いコマンドとかもありそうだし・・・)~~


## VORON公式サイト
- 信頼できる：★★★★★
- 情報量　　：★★★☆☆
- 銀の弾丸度：★★★☆☆

[VORON](https://docs.vorondesign.com/about.html)は、ユーザーが自分で材料を集め(主に自作）て構築する3Dプリンタのプロジェクトです。[スペックの高さ](https://youtu.be/a6XRs-g6ngw)には定評があるものの敷居が高いのが特徴です。
（私個人的には、3Dプリンタ界のGentooLinuxだと思っています。~~初めての3DプリンタでVORONをオススメする人からは距離をおいたほうが良い~~ ）

[チュートリアル](https://docs.vorondesign.com/community/howto/voidtrance/Klipper_Macros_Beginners_Guide.html)はもっと丁寧ですし、[github](https://github.com/VoronDesign)には実際の例が記載されています。ただ、自分のプリンタがVORONではない限り、結構読み替えが必要です。


## Reddit
- 信頼できる：★★☆☆☆
- 情報量　　：★★☆☆☆
- 銀の弾丸度：☆☆☆☆☆～★★★★★
Klipperの情報が多いのは日本より海外です。そうなると検索結果には自然とRedditの投稿が引っかかります。
直球で役に立つ情報が乗っていることもありますが、スライサとの連携を前提とした応用的なコードであることが多く、自分のマクロには応用し辛い。もちろんぴったりなものが見つかれば嬉しいですが。

# 次回
実際にマクロを書いてみようと思います。
[後編](https://qiita.com/tanutanup/items/433b3701a39a6fe7d37b)に続く。
@googlemaps/react-wrapperでgoogleの型定義を追加する方法

[`@googlemaps/react-wrapper`](https://www.npmjs.com/package/@googlemaps/react-wrapper)は、React用のGoogle Mapsのライブラリです。

TypeScriptで使用する時に型定義エラーが出た時の対処法になります。

## 出現するTypeScriptの型定義エラー

```jsx
 const [map, setMap] = useState<google.maps.Map>()
```
```
名前空間 'google' が見つかりません。
```
![googlemaps-react-wrapper.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559347/9ba1f54a-d7f8-dba4-a9bd-28ab50bfda99.png)
## 対処法

`@types/google.maps`の型定義をインストールすることでエラーは解消されます。

```
npm i @types/google.maps
#OR
yarn add @types/google.maps
```

![googlemaps-react-wrapper-google.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559347/1783bde2-c853-5c35-bd27-35615b1230fe.png)

## 参考

https://www.npmjs.com/package/@googlemaps/react-wrapper

https://www.npmjs.com/package/@types/google.maps
git pullするとhintがたくさん出てくる

備忘録の記事です。
ローカルでgit pullした時に、hintとかわらわら出てきました。

# やりたいこと
この警告？を非表示にしたい

```
% git pull origin main
hint: Pulling without specifying how to reconcile divergent branches is
hint: discouraged. You can squelch this message by running one of the following
hint: commands sometime before your next pull:
hint: 
hint:   git config pull.rebase false  # merge (the default strategy)
hint:   git config pull.rebase true   # rebase
hint:   git config pull.ff only       # fast-forward only
hint: 
hint: You can replace "git config" with "git config --global" to set a default
hint: preference for all repositories. You can also pass --rebase, --no-rebase,
hint: or --ff-only on the command line to override the configured default per
hint: invocation.
From https://github.com/tomoya007/movie-review
 * branch            main       -> FETCH_HEAD
Already up to date.
```

# 解決法
メッセージにあるように、以下の 3 つの設定のうち、いずれかを実施すれば、 warning は出なくなります。

・```git config pull.rebase false```
・```git config pull.rebase true```
・```git config pull.ff only```

一旦```git config pull.rebase false```してみる
```
% git config pull.rebase false
chiharatomoya@rooter movie-reivew(オリジナル版) % git pull origin main
From https://github.com/tomoya007/movie-review
 * branch            main       -> FETCH_HEAD
Already up to date.
```

とりあえずwarningは出なくなった。

特に、今までの動作に不満がないという人は ```git config --global pull.rebase false``` をやっておけば、今までの挙動の通り、 ```warning``` だけ出なくなります。


# git pull 操作の選択肢
先程の ```warning``` に対処するための 3 つの選択肢を考えたいのですが、その前に、 ```git pull``` の ```--rebase option``` について確認します。
何も指定しない場合は、 ```--rebase false``` と同じで、これがデフォルトの動作です。 ```--rebase``` を指定した場合は ```--rebase true``` と同じです。

# 3 つの選択肢を選んだ場合の挙動
ここまでくれば、 git pull にオプションを付けずに実行したときの動作について、 Git が以下のいずれかを要求していることが分かります。

## git config pull.rebase false
デフォルトの挙動です。```git pull``` に ```--rebase option``` を付けずに実行するのと同じです。
標準動作では ```rebase``` せずに ```fast-forward``` 可能な場合は ```fast-forward``` を行い、そうでない場合は、 ```merge commit``` を生成しようとします。

## git config pull.rebase true
```git pull --rebase``` を行う場合と同じです。
```git fetch``` を行った上で、ローカルブランチに対して ```rebase``` を実施するので、```merge commit``` が作られずに、コミット履歴が一直線になります。

## git config pull.ff only
```--ff-only option``` を付けた時と同様、 ```fast-forward``` 可能な場合のみ、 ```fast-forward``` します。
そうでない場合は、 ```merge/rebase``` せず、エラー終了します。

参考：

https://qiita.com/tearoom6/items/0237080aaf2ad46b1963
rails console の基本

## はじめに


rails console は、Ruby on Rails アプリケーションのための対話型のコマンドラインツールです。これを使って、アプリケーションの環境を操作したり、データベースとやり取りしたり、デバッグやトラブルシューティングを行ったりできます。以下に、rails console の基本的な使い方を説明します。

## 起動方法
ターミナル（コマンドプロンプト）で、Rails アプリケーションのルートディレクトリに移動し、以下のコマンドを入力して rails console を起動します。
```ruby
rails console #rails c でも可
```
また、特定の環境（例：開発環境や本番環境）でコンソールを起動したい場合は、以下のように環境を指定して起動できます。
```ruby
rails console development
```

## モデル操作
rails console では、アプリケーションのモデルにアクセスして、データベースの操作が可能です。例えば、User モデルの全てのレコードを取得するには、以下のコマンドを入力します。
```ruby
User.all
```

新しい User レコードを作成するには、以下のように入力します。

```ruby
User.create(name: "John Doe", email: "john.doe@example.com")
```

特定の条件に一致するレコードを検索するには、以下のように入力します。

```ruby
User.where(email: "john.doe@example.com")
```
## メソッド実行
アプリケーション内のメソッドや関数を実行することもできます。例えば、以下のようにして、ユーザーがログインしているかどうかを確認できます（仮定：current_user メソッドが定義されている場合）。

```ruby
current_user.logged_in?
```

## 終了方法
rails console を終了するには、exit または quit と入力します。
```ruby
exit
```
## 最後に
以上が rails console の基本的な使い方です。データベースの操作やアプリケーションの状態の確認、デバッグなどに活用できます。また、rails console はアプリケーションのコードをリアルタイムで評価するため、実験や検証にも役立ちます。
react-hooks-use-modalを使ってみる

# react-hooks-use-modalを使ってみた
ログアウト時などにモーダルを表示させたいと思ったので色々ライブラリを調べていたところ`react-hooks-use-modal`という便利なものを見つけたので実装してみたいと思います。
今回は、CSSなどの装飾はせずにあくまでもモーダルの実装だけを行います。

# インストール
Reactで使用していくので、まずはインストールします。yarnの場合はnpmをyarnに変えるだけでオッケーです。
```
$ npm install react-hooks-use-modal
```
# useModal
使い方としては、`useModal`というAPIを使用します。
まずは、利用するコンポーネントに先ほどインストールしたものをインポートします。
```jsx
import { useModal } from 'react-hooks-use-modal';
```
useModalには4つの機能が存在します。
* Modal ・・・　コンポーネントで画面中央に表示される
* open　・・・　モーダルを開く
* close　・・・モーダルを閉じる
* isOpen　・・・モーダルが開いているかどうかを知る真偽値

```jsx
const [Modal, open, close, isOpen] = useModal('root', {
    preventScroll: true,
    focusTrapOptions : { 
       clickOutsideDeactivates : false
    },  
  });
```
`root`の部分は、HTMLのdivタグに指定してあるidを設定します。
`preventScroll: true `は、モーダル表示後のスクロールを抑制してくれます。falseにするとスクロールすることができるようになります。
`focusTrapOptions`に`clickOutsideDeactivates : false`を指定することでモーダル表示中にクリックしてもモーダルが閉じなくなります。

# 実際に使用してみる
今回はログアウトボタンをクリックした時に、モーダルを表示してみます。

```jsx
<div>
    <button onClick={open}>ログアウト</button>
</div>
<Modal>
    <div>
        <h1>ログアウトしますか？</h1>
        <button onClick={logout}>はい</button>　// logoutメソッドはログアウトの機能を実装してください。
        <button onClick={close}>いいえ</button>
    </div>
</Modal>
```
`open`メソッドを使用することでログアウトボタンを押した時に`Modal`コンポーネントでラップしたコンポーネントを画面中央に表示することができます。
`close`メソッドを使用することでモーダルを閉じることができます。

# 最後に
今回はモーダル表示の必要最小限の機能にとどめましたが、CSSなどで自分なりにデザインしてもらえるとUIの良いモーダルを実装することができると思います。

# 参考記事
https://blog.microcms.io/how-to-react-hooks-use-modal/
【GitHub】Packageを削除する方法

## パッケージを削除する方法
パッケージは以下の手順で削除します。

リポジトリの「Code」の画面右下「Packages」欄のパッケージ名をクリックします。
![スクリーンショット 2022-09-30 18.18.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/fe046150-2e92-8fd2-03af-b04ee50c2a99.png)

するとインストール方法などが記載されたページが開きます。
このページ右下の「Package settings」をクリックします。
![スクリーンショット 2022-09-30 18.19.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/63a3719f-3c28-2603-a07e-326b7123fe45.png)

開いたページ赤枠内の「Delete this package」をクリックし削除します。
![スクリーンショット 2022-09-30 18.19.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/17fdf4de-44f5-e935-45b8-cf8d8ddfb470.png)
【Swift】for文内のif letを省略できるらしい

# はじめに
Twitterで流れてきたツイートでこんなことができるんだ。。。
と思ったことがあったので記録しておきます。

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">Swift has a `for-case-let` syntax, which is equivalent to the `for-in...if-let` syntax. The former makes code cleaner but less expressive.<br>Personally, I would prefer to use the latter syntax to keep my code expressive. I wonder how commonly the `for-case-let` syntax is used. 🤔 <a href="https://t.co/Fngk9h4e40">pic.twitter.com/Fngk9h4e40</a></p>&mdash; Lee Kah Seng (@Lee_Kah_Seng) <a href="https://twitter.com/Lee_Kah_Seng/status/1640950212482019328?ref_src=twsrc%5Etfw">March 29, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

以前書いたこちらの記事と似ていますね

https://qiita.com/SNQ-2001/items/c9e483dab6d9e23f2dbc

色々なリファクタ術があって面白いです。

ツイートの画像が全てなのですが、一応記録しておきます。

# 実装
```swift:データ
let characters: [String?] = [
    "アイアンマン",
    "キャプテン・アメリカ",
    nil,
    "スパイダーマン",
    nil,
    "ハルク"
]
```
```swift:実装パターン1
for character in characters {
    if let character {
        print(character)
    }
}
```
```swift:実装パターン2
for case let character? in characters {
    print(character)
}
```

# おまけ
```swift
characters
    .compactMap { $0 }
    .map { print($0) }
```

# おわり
いろんな実装方法があって面白いです
Mac VScodeのターミナルのデフォルトshellをzsh → bashに変更する

# 概要

- VScodeのターミナルでデフォルトのshellをbashにする方法をまとめる。

# 前提

- 下記の内容を実施済み。

https://qiita.com/miriwo/items/79f377a5301540675334

# 方法

1. VScodeを開く。
1. VScodeのターミナルを開く。
1. ターミナルの「+」の横の下矢印をクリックする。

    ![Visual_Studio_Code.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/e12fadf8-2626-9ec9-01ca-3db01fec6ecf.png)

1. 「既定のプロファイルの選択」をクリックする。

    ![スクリーンショット 2023-03-29 21.46.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/b43c947d-fdd0-320b-5df3-abf21c2a93eb.png)

1. 「bash」をクリックする。

    ![スクリーンショット 2023-03-29 21.47.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/956cc78a-aacd-7f0a-57f4-7396d1a46488.png)

1. VScodeを再起動してVScodeのターミナルを起動する。
1. デフォルトがbashになった。

    ![ようこそ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/adb5f58f-b858-72d6-ae74-8b224720b5de.png)
依存配列にメモ化した関数を入れるよりも、その関数をフックで定義しよう

# 結論

**useMemo、useEffectなどで呼び出す関数は、そのフックの中で定義します。**

# useCallbackでメモ化した関数をフックで使用したくない理由

公式ドキュメントに As a last resort （最後の手段）と記載されていたからです。
>As a last resort, you can add a function to effect dependencies but wrap its definition into the useCallback Hook. This ensures it doesn’t change on every render unless its own dependencies also change:

https://legacy.reactjs.org/docs/hooks-faq.html#performance-optimizations

理由はわかりませんが、公式がそう言っているので従うべきだと思いました。
いつかちゃんと理由を調べたいです……。

# 例


こうではなくて……
```
export const Component = (props) => {
    const { data } = props;
    
    const hoge = useCallback(() => {
        console.log(data);
    }, [data]};
    
    useEffect(() => {
        hoge;
    }, [hoge];
    
    // (省略)
};
```

こうします！
```
export const Component = (props) => {
    const { data } = props;
    
    useEffect(() => {
        const hoge = () => {
            // (処理省略)
        };
    
        hoge();
    }, [data]);

    // (省略)
};
```

# 参考

https://legacy.reactjs.org/docs/hooks-faq.html#performance-optimizations

https://zenn.dev/kimromi/articles/b5b29c97533e05
オーダー記法 (Big O 記法) について

## オーダー記法 (Big O 記法) 
アルゴリズムの計算量を表すために使用される記法
アルゴリズムの計算量は、入力サイズに応じて変化します。オーダー記法は、アルゴリズムの計算量が入力サイズに対してどのように増加するかを表します。

## 具体的な表記例

- 定数時間（O(1)）: 入力サイズに関わらず、常に一定の計算量で処理を行うアルゴリズムです。例えば、配列の先頭要素を取得する操作はO(1)です。

- 対数時間（O(log n)）: 入力サイズが倍々になるごとに、計算量が1増加するアルゴリズムです。例えば、二分探索はO(log n)です。

- 線形時間（O(n)）: 入力サイズに比例して計算量が増加するアルゴリズムです。例えば、配列の全要素を順に処理する操作はO(n)です。

- 二次時間（O(n^2)）: 入力サイズの2乗に比例して計算量が増加するアルゴリズムです。例えば、二重ループを使ったソートアルゴリズムはO(n^2)です。

- 三次時間（O(n^3)）: 入力サイズの3乗に比例して計算量が増加するアルゴリズムです。例えば、3重ループを使った行列演算はO(n^3)です。

- 指数時間（O(2^n)）: 入力サイズが1増えるごとに計算量が2倍になるアルゴリズムです。例えば、部分集合の列挙にはO(2^n)のアルゴリズムが必要です。

- 階乗時間（O(n!)）: 入力サイズの階乗に比例して計算量が増加するアルゴリズムです。例えば、全順列の列挙にはO(n!)のアルゴリズムが必要です。


オーダー記法は、アルゴリズムの計算量を比較するために広く使用されています。一般的に、より効率的なアルゴリズムは、より小さなオーダー記法を持ちます。たとえば、O(n log n)のアルゴリズムは、O(n^2)のアルゴリズムよりも効率的です。

## 注意点
オーダー記法は、アルゴリズムの実行時間を正確に予測するための方法ではありません。アルゴリズムの実行時間には、計算量以外にも多くの要因が影響することに注意する必要があります。また、アルゴリズムの実装方法によって、オーダー記法が異なることがあります。したがって、アルゴリズムの実行時間を予測する際には、オーダー記法を一般的な見積もりとして使用する必要があります。


また、オーダー記法は、アルゴリズムの計算量が入力サイズに応じてどのように増加するかを表すため、特定の問題について最適なアルゴリズムを見つけるためのヒントを与えることができます。たとえば、入力サイズが非常に大きい場合には、O(n log n)のアルゴリズムが適切である場合があります。

一般的に、アルゴリズムの計算量が小さいほど、アルゴリズムの実行速度は高速になります。そのため、アルゴリズムを実装する際には、できるだけ小さなオーダー記法のアルゴリズムを選択することが望ましいとされています。

ただし、実際には、アルゴリズムの計算量を小さくするためには、コードの最適化やアルゴリズムの改良が必要になる場合があります。そのため、アルゴリズムの計算量を考慮した上で、プログラムの機能や実装の複雑さ、保守性などの要素を総合的に判断する必要があります。

## 最後に
オーダー記法はプログラミングの分野だけでなく、データ構造やアルゴリズムの分野でも使用されます。データ構造の操作の計算量を表現する場合には、検索、挿入、削除などの操作の計算量を考慮する必要があります。また、アルゴリズムの最悪時間計算量、平均時間計算量、空間計算量など、さまざまな計算量の指標が存在します。

オーダー記法は、計算量の見積もりにおいて非常に役立つ記法であり、プログラミングやアルゴリズムの学習においては必須の概念です。



以上のオーダー記法により、アルゴリズムの計算量の見積もりや最適化が行われます。ただし、現実的には、入力サイズが非常に大きい場合には、O(1)やO(log n)であっても実行時間が長くなる場合があります。そのため、アルゴリズムの実行速度を評価する際には、オーダー記法だけでなく、実際の実行時間も考慮する必要があります。