OmniAICreator/Qiita-1.07M huggingface dataset:
Rustで不要なディレクトリを削除する

### rmコマンド

Rustでは、ディレクトリの削除はrmコマンドで行える。

```
rm ファイル名
```

### rmコマンドのオプション

|No|オプション|オプションの意味|
|---|---|---|
|1.|-r|ディレクトリの内容を削除|
|2.|-f|エラーを無視する|
|3.|-i|削除前に確認する|
|4.|-v|経過を表示する|

### 実行サンプル

helloディレクト内のa.txtファイルを削除してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3533750/f63cef0b-46cf-ad2d-5b76-d53b698834d9.png)

警告のようなものは出てしまいましたが
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3533750/ed375692-a06e-f978-bfef-7bbbefdf139b.png)

ファイルは無事削除されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3533750/05fbbd86-f274-110e-e23c-8013c1be049e.png)
Beginner picoMini 2022 writeup convertme.py

## convertme.py (General Skills)

Run the Python script and convert the given number from decimal to binary to get the flag.

添付ファイル
・convertmy.py

とりあえず実行してみると、
```
> python convertme.py 
If 69 is in decimal base, what is it in binary base?
Answer: 1000101
That is correct! Here's your flag: picoCTF{4ll_y0ur_b4535_722f6b39}
```
フラグが得られた。指示通り10進数を2進数に変換するだけで良い。

`picoCTF{4ll_y0ur_b4535_722f6b39}`
windows11でzipファイルの解凍ができない場合の対処法

# 現象
ダウンロードしてきたzipファイルを右クリック→すべて展開で解凍しようとするとエラーが起こる。

# 原因
ファイルが大きすぎるため。
windows標準のzipツールでは2GB以上のzipファイルは解凍できないらしい

# 対処方法
他のzipツールを用いるなど様々あるが、今回は`Expand-Archive`コマンドレットを用いた。
※コマンドレット：PowerShellで標準で利用可能なコマンドのこと

以下のコマンドをpower shellから実行すると解凍できる

```
Expand-Archive -Path {zipのパス} -DestinationPath {展開先のディレクトリ}
```


# 参考
https://learn.microsoft.com/ja-jp/powershell/module/microsoft.powershell.archive/expand-archive?view=powershell-7.4

https://learn.microsoft.com/ja-jp/powershell/scripting/discover-powershell?view=powershell-7.4#powershell-cmdlets
Beginner picoMini 2022 writeup Codebook

## Codebook (General Skills)

Run the Python script code.py in the same directory as codebook.txt.

添付ファイル
・code.py
・codebook.txt

同じディレクトリで実行すればフラグが得られそう。コマンドプロンプトに`python code.py -d codebook.txt`を投げたらフラグが出てきた。

`picoCTF{c0d3b00k_455157_d9aa2df2}`
URLごとの毎日のインプレッション数とクリック数の可視化

## 1. はじめに

この記事では、Google Search Console（GSC）のデータをGoogle BigQueryを使用して集計し、その結果をLooker Studioで可視化する方法を解説します。最終的には毎日のサイトのインプレッション数とクリック数を折れ線グラフに表示しました。本記事の内容はBigQueryに焦点を当てています。GCPやLooker Studioの設定に関する具体的な手順については今後別の記事で詳しく説明する予定ですので、気長にお待ちいただくか、他の記事を参考にしてください。

この記事はChatGPT-4oを使用して作成されており、内容に誤りがあるかもしれません。詳細まで見れていないので、間違い等ありましたらご指摘いただけると助かります。

## 2. 結果の可視化

以下は、URLごとの毎日のインプレッション数とクリック数を表示した折れ線グラフの例です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2496939/532c4e6f-6f99-b725-1338-15368e89a419.png)


## 3. データの抽出

まず、BigQueryを使用して、GSCデータから必要な情報を抽出します。以下のSQLクエリを実行して、URLごとの毎日のインプレッション数とクリック数を集計します。

```sql
CREATE OR REPLACE TABLE `your_project.your_dataset.url_daily_performance` AS
SELECT
  data_date,
  url,
  SUM(impressions) AS total_impressions,
  SUM(clicks) AS total_clicks
FROM
  `your_project.your_dataset.searchdata_url_query`
GROUP BY
  data_date, url
ORDER BY
  data_date ASC, url;
```
このクエリは、各URLのインプレッション数とクリック数を日付ごとに集計し、url_daily_performanceテーブルに格納します。

## 4. Looker Studioでの可視化
### 4-1. データソースの設定
Looker Studioにログインし、新しいレポートを作成します。
「データソースを追加」をクリックし、「Google BigQuery」を選択します。
プロジェクト、データセット、およびurl_daily_performanceテーブルを選択します。
### 4-2. 折れ線グラフの作成
レポートキャンバスに戻り、「チャートを追加」ボタンをクリックし、「折れ線グラフ」を選択します。
折れ線グラフをクリックし、右側の「データ」タブで以下のように設定します：
次元（Dimensions）: data_date
指標（Metrics）: total_impressions
URLごとにフィルタを設定するため、フィルタアイコンをクリックし、urlを選択して表示したい特定のURLを設定します。
同様の手順で、新しい折れ線グラフを追加し、total_clicksを指標として設定します。
## 5. まとめ
この手順を使用して、Google Search ConsoleデータからURLごとの毎日のインプレッション数とクリック数を抽出し、Looker Studioで可視化する方法を紹介しました。この可視化により、各URLのパフォーマンスを詳細に分析し、SEO対策の改善点を見つけることができます。
## 6. 関連記事
[tan0ry0(2024.6), BigQueryを用いたGSCデータの可視化とLooker Studioでの表示](https://qiita.com/tan0ry0shiny/items/fb361307e65abe9e93ce)
MinIOでS3のMockをしたときにpresigned URLで困った話


S3を使うプロジェクトをローカル環境でテストしたいことないでしょうか？
そんな時には、MinIOが便利です。

https://min.io/

MinIOはS3 APIのmockとして使える上に、コンソールまで提供してるので今のバケットの状態をGUIで見れて便利です。
さて、MinIOからpresigned URLを発行しようとした際に詰まったので残しておこうと思います。


# MinIOの設定

MinIOは公式のdocker imageがあるのでそれを使用します。

```dockercompose.yaml
services:
  minio:
    image: quay.io/minio/minio:RELEASE.2024-05-28T17-19-04Z
    container_name: minio
    environment:
      MINIO_ROOT_USER: ${MINIO_ROOT_USER}
      MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD}
      # ここがないと後述の問題になる
      MINIO_DOMAIN: ${MINIO_DOMAIN}
    ports:
      - 9000:9000
      - 9001:9001
    restart: unless-stopped
    command: ['server', '/data', '--console-address', ':9001']
    volumes:
      - minio_data:/data
volumes:
  minio_data:
```
上のcomposeのファイルはどっかから拾ってきたものを編集したものです。
ポートが9000番と9001番二つ空いているのは、minioはAPI用とブラウザのコンソール用で二つ使うからです。
環境変数については後で触れます。

# presigned URL

presigned URLとは、S3のオブジェクトをGETやPUTする際に、APIサーバーなどに直接データを経由させることなく、S3とクライアントでデータのやり取りができる仕組みです。
具体的には、GETの場合、APIサーバーがアクセスされた際に、一時的に使えるURLを発行し、
そのURLにリダイレクトさせたりします。
PUTの場合は、PUTする前にpresigned URLを発行してそこに対してPUTさせるようにしたりします。
presigned URLには期限を設けることができて、その期間を過ぎたリクエストを無効化してくれたりします。

# presigned URLを取得してみる

さて、presigned URLを発行するAPIを叩いてAPIを発行します。
自分はRustのsdk経由で発行してます。

```rust
// clientの作成
let config = aws_config::defaults(BehaviorVersion::v2024_03_28())
    .load()
    .await;
let client = aws_sdk_s3::Client::new(&config);
// urlの取得
let response = client.get_object()
      .bucket(bucket_name)
      .key(object_key)
      // 変更されていなかったらHTTPステータスコードの304を返却してくれる
      .set_if_none_match(get_if_none_match(&headers))
      // presigned Requestを行う。 
      // presigned_configはExpireを設定したコンフィグを返す独自定義の関数
      .presigned(presigned_config()) 
      .await?;
```
あとは、urlを返却します。axumでサーバーを立てた時のは以下の様に返却します
```rust
match response {
    Ok(response) => {
        let uri = response.uri();
        // etagとかをheaderで返しておくと if-none-matchで使える
        Ok((AppendHeaders(out.headers()), Redirect::temporary(uri)))
    }
    Err(e) => {
        Err(e)
    }
} 
```

# presigned URLが無効...？

困ったこととして、presigned URLを発行したときに、正しく取得したはずなのに、
そのURLを使ってもGETできないということがありました。

```
The specified bucket is not valid.
```

コンソールなどで確認しても確かにバケットがあることが確認できます。
なんでこのようなエラーになるのでしょうか？

# S3のpresigned URLの形式

得られたpresigned_urlのドメインは`index.localhost`になってました。
確かに得ようと思ったバケット名は`index`です。なぜサブドメインがこのように設定されているのでしょうか。

これはS3のpresigned_urlの形式に由来してます。
S3は2019年以降、仮想ホスト形式というURLの形式に移行していて、
`http://<bucket-name>.s3.amazonaws.com`という形式になっています。

ただそれ以前はパス形式という`http://s3.amazonaws.com/<bucket-name>`のようにパスにバケット名を入れる方式を利用していたそうです。

https://dev.classmethod.jp/articles/s3-no-longer-support-path-style-requests/

Rustのsdk clientには[force_path_style](https://docs.rs/aws-sdk-s3/latest/aws_sdk_s3/config/struct.Builder.html#method.force_path_style)という設定があり、これを使うと問題なく取得できました。

ただ記事にある通りこの形式では本番のS3にアクセスできないので、どうにかしたいです。

# MinIOの設定

MinIOはデフォルトではパス形式を使うので、仮想ホスト形式に切り替えないといけないです。
解決策は、MinIOに`MINIO_DOMAIN`の設定を渡すだけでした。これで仮想ホスト形式でも、
MinIOがそのURLでアクセスしてObjectの取得ができました。

https://min.io/docs/minio/linux/administration/object-management.html#minio-object-management-path-virtual-access

# 終わりに

原因がわかりづらくて調査がつらかった…。
そもそも5年前に廃止された方式がなぜ今もデフォルトなのか…。
Go テスト時の構造体の比較方法

# Goの構造体の比較の方法についてメモ

## 結論
go-cmp便利
シンプルな比較であればassert.Equalで十分。

ちょっと複雑なことをやるならgo-cmpを使うとよい。
例えば以下はよくあるケースだと思う。
- 日付など特定のカラムを除外して比較したい
- 構造体の配列の比較の際に並び順は無視して比較したい

## 調べた経緯
比較するのはいくつか方法があるのでどれが良いのか気になったため。

- ObjectsAreEqual
https://pkg.go.dev/github.com/stretchr/testify/assert#ObjectsAreEqual

- assert.Equal（内部でObjectsAreEqualを呼びだしている）
https://pkg.go.dev/github.com/stretchr/testify/assert#Equal

- DeepEqual
https://pkg.go.dev/reflect#DeepEqual

- go-cmp
https://pkg.go.dev/github.com/google/go-cmp/cmp
https://pkg.go.dev/github.com/google/go-cmp@v0.6.0/cmp/cmpopts#IgnoreFields

## go-cmp使い方例

- 比較時に配列の場合に並び順を気にせず、比較したい
- 特定のカラムを比較対象外にしたい

以下は結果はokとなる

```golang
package xxxx

import (
	"testing"

	"github.com/google/go-cmp/cmp"
	"github.com/google/go-cmp/cmp/cmpopts"
)

func Test_xxxx(t *testing.T) {

	type StructA struct {
		ID        int
		Name      string
		CreatedAt time.Time
	}

	expected := []StructA{
		{
			ID:        1,
			Name:      "A",
			CreatedAt: time.Now(),
		},
		{
			ID:        2,
			Name:      "B",
			CreatedAt: time.Now(),
		},
	}

	result := []StructA{
		{
			ID:        2,
			Name:      "B",
			CreatedAt: time.Now(),
		},
		{
			ID:        1,
			Name:      "A",
			CreatedAt: time.Now(),
		},
	}

	// 比較時は並び順は考慮しない・created_atは比較対象外にする
	opt := cmp.Options{
		cmpopts.SortSlices(func(a, b StructA) bool {
			return a.ID < b.ID
		}),
		cmpopts.IgnoreFields(StructA{}, "CreatedAt"),
	}

    // オプション(opt)を用いて比較
	diff := cmp.Diff(expected, result, opt)
	if diff != "" {
		t.Errorf("(-expected, +result)\n%s", diff)
	}

```
【ChatGPT＋DALL-E3】絵文字で画像生成


　どうも、カーブミラーです。

　今回は、絵文字で画像生成をします。以前にも書きましたが、今回は絵文字の指定をChatGPTに任せます。

:::note info
本記事は、ChatGPT（有料版）
＋DALL-E3で行なっております。
画像はあります。　あしからず。
:::

　昨日（2024/06/09）も
　　今朝も、ChatGPTさんが
　　　動かなくなったです😭

　まぁ、先日よりも
　　短く済んだので、
　　　それほど支障は
　　　　なかったですけどね。
***
　さて、本題です。

　IT naviさんが
　　また、Promptを
　　　公開してくださいました。

　以前に、
　　絵文字を使って、
　　　描画することを書きました。
[【ChatGPT有＋DALL-E3】こんなの、あり？　絵文字や顔文字で？](https://qiita.com/kabumira/items/a7160e28502c72f5fbe1)

　今回は、
　　これの応用になります。

　ポストはこちら。
[IT naviさんポスト](https://x.com/itnavi2022/status/1799964919175258376?t=3ytmvKVYqg_0Ytgf98xiDA&s=03)

　まずは、
　　Promptを
　　　ごらんください。
```Text:IT naviさん絵文字Prompt
幻想的で優美な絵になるように３つの絵文字を選択し、それをプロンプトとして画像を生成して
```
　どこにも
　　絵文字がありません。

　そうです。
　　絵文字はChatGPTに
　　　選ばせるんです。

　ランダムに、
　　ではありません。

　これは別に
　　絵文字を使用する
　　　必要はないんですよ😅

　そうなるように
　　Prompt作成を
　　　ChatGPTに依頼すれば
　　　　出来上がります。

　絵文字を使う、
　　というアイディアが
　　　面白いのですね。

　さて、
　　IT naviさんのこのPrompt、
　　　幻想的で優美な絵にしか
　　　　対応できません。

　そこで
　　ここの部分を
　　　指定できるように
　　　　括弧でくくります。

　[IMAGE]を変えれば、
　　あなたのイメージに
　　　沿った画像を生成できます。

　また、
　　“３つ”と指定されていますが、
　　　もちろん、変更可能です。
　　　
```Text:IT naviさん絵文字Prompt改
[IMAGE]になるように３つの絵文字を選択し、それをプロンプトとして画像を生成して
```

　試しに
　　[IMAGE]を
　　　“電化製品ばかりの部屋の絵”に
　　　　変更してやってみました。

　💻 (ノートパソコン)、
　　📺 (テレビ)、
　　　🎧 (ヘッドフォン) が
　　　　選択されて、画像生成すると
![1717987045131.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457238/89b3134d-bf18-d427-21b7-7573d8694be0.jpeg)
　　　　　となります。

　みなさんの
　　作品制作の糧に
　　　なれば、幸いです。

　今回は、ここまで。
【Linux入門】特定のユーザーに特定のプログラムのみsudo権限を付与する

# 環境

- AlmaLinux8.9

# Sudo権限を付与する

ユーザーの`sudo`権限を管理するには`/etc/sudoers`ファイルを編集することで行えます。

- **構文**

```/etc/sudoers
<username> <hostname.example.com>=(<run_as_user>:<run_as_group>) <path/to/command>
```

- **解説**
    - `<username>`
        - コマンドを入力するユーザー
        - `%`で始まる場合はグループを定義(例: %users)
    - `<hostname.example.com>`
        - ルールが適用されるホスト名
    - `(<run_as_user>:<run_as_group>)`
        - コマンドを実行するユーザーまたはグループを定義
        - 省略するとroot としてコマンドを実行
    - `<path/to/command>`
        - コマンドの絶対パス
        - パスの後にオプションを追加することで特定のオプションを制御可能
        - オプションなしの場合は全てのオプションが有効

:::note alert
それぞれの項目は`ALL`に置き換えることができ、その場合は全てのユーザーなどを指定することができるので要注意
:::

:::note info
`!`演算子を使用することができ、`!root`とした場合は`root`以外のすべてのユーザーを指定できる。
:::

- **例**

```/etc/sudoers
user ALL = /usr/bin/python3.11, /usr/bin/zip
```

# 参考サイト

https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/8/html/configuring_basic_system_settings/managing-sudo-access_configuring-basic-system-settings

https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/8/html/configuring_basic_system_settings/granting-sudo-access-to-a-user_managing-sudo-access
Diver OSINT CTF writeup

# 初めに

Diver OSINT CTFに出場しました！！！
とても楽しかったです！！
2日目に、寝坊して解ける問題が少なかったのですが、参加記念としてwriteupを挙げておきます。（一問だけです（笑））

### チーム成績
57th / 453team
2403pt

### 個人成績
2問 / 257pt

## ad_directiare
>この名刺の人物が、東京出張時に食べた昼ご飯の値段を答えよ。
Flag形式: Diver24{値段}
1000円の場合、Flagは Diver24{1000} となります。

![ad_directiare.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3805709/047389cf-8efb-5781-7d76-d9a891d3a35c.jpeg)

メールアドレスの「yone.jun.0727@gmail.com」を検索してみた。
使用したのは以下のサイト。
https://epieos.com/

すると、google mapのレビューが出てきて、値段が書いてある。

### 余談（解けなかった問題)
![246.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3805709/dd086dea-aa4f-8d89-c3a7-571e27617bca.jpeg)
>画像が撮影された場所から最も近い交差点名を答えよ。
Flag形式: Diver24{交差点名}

246：大体の位置（山口県の県道246号）は分かったが、ストリートビュー時に見逃していた。

![chiban.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3805709/6ac45ff8-67fb-fcc0-a91c-9fd8dd512983.jpeg)

>画像の中央に写っている道路の地番は何か。
たとえば住所が 仙台市宮城野区二十人町 303-8 の場合、Flagは Diver24{303-8} となる。
また、地番には数字だけでなく漢字が含まれることもある。その場合は漢字表記のまま解答せよ。

chiban：写真の場所（大阪府茨木市双葉町）は分かったが、地番まで特定することができなかった。（正解はDiver24{筆界未定地-6}だったのだが、私はDiver24{-6}と入れていた。悔しい...）

![DSC_8886.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3805709/585030c1-64f6-e111-5be7-7cb8551c2718.jpeg)
>画像の撮影された郷土料理屋の店名を答えよ。
Flag形式: Diver24{店名}

imagetrack：会社名までたどれたが、郷土料理屋まで到達できず（チームメンバーが後ほど問いてくれました！）

![championships.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3805709/d73e3694-d57f-4529-5215-41558068554f.jpeg)
>medium
2010年10月、この場所には大会の広告が貼られていた。その大会の優勝者のニックネームを答えよ。
Flag形式: Diver24{優勝者のニックネーム}

場所（光華商場）は分かったが、2010年の画像がなかった。
どうやら、google mapのストリートビューにあるらしい。何で見なかった...

# 感想

久々のOSINT CTFで難易度高かったけど、とても楽しかった！！！
ただ、時間が取れなかったことが悔やまれる...

来年も開催するかな？（ワクワク）
個人開発したのでプロセスをまとめてみる

# はじめに
個人開発を行ったので、その時に背景や技術選定、開発プロセスなどをまとめてみたいと思います。実質初めて記事を書くので不自然な文章があると思いますが、温かい目で見てくれると幸いです。

webアプリのurl

https://tech-books-study.vercel.app/register

githubコード(バックエンド)

https://github.com/kodainn/RTBP_backend

githubコード(フロントエンド)

https://github.com/kodainn/RTBP_frontend

# 個人開発を行った背景
以前はプログラミングのアルバイトが忙しくて、全然できていなかったのですが、それが落ち着いてきて新しい技術を使って何か作りたいなと思い至りました。

# 開発プロセス
私の個人開発のプロセスは以下の通りです。
アイデア出し
↓
アイデアをもとに要件を洗出す
↓
figmaでのデザイン
↓
技術選定＆デプロイ先の決定
↓
フロントエンドのコンポーネント、フォルダ構成設計
↓
フロントエンドのデザイン実装
↓
データベース論理設計
↓
バックエンドのフォルダ構成設計
↓
バックエンドAPIの実装
↓
バックエンドAPIをもとにフロントエンドの機能を実装
↓
バックエンド、フロントエンドをデプロイ

# アイデア出し
身近なところで何か困ったことはなかったかを考え、私の場合だとよく技術を使った勉強する機会が多く、読み切れていない書籍があるのに新しく書籍を購入して積読状態になることがあったので、その問題を解決できるようなアプリを開発しようと至りました。

# 要件の洗出し
figmaを用いて要件を整理しました。
メモに要件を洗出すことでどのような機能が必要になってくるかを整理することができました。
![スクリーンショット_10-6-2024_103614_www.figma.com.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538192/590b5bbd-f829-0233-21f3-e29770e1a0cf.jpeg)
# figmaでのデザインについて
どのようなアプリにするかをfigmaを用いてデザインしました。
ここでフロントエンド側で必要な要素やバックエンドの機能で何が必要なのかを整理することができました。
![スクリーンショット_10-6-2024_10394_www.figma.com.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538192/a913ced2-4bf5-3690-42e3-f5d73709e56b.jpeg)

# 技術選定＆デプロイ先の決定
技術選定は以下の通りです。
バックエンド
- python
- fastAPI
- sqlalchemy
- pydantic
- uvicorn

フロントエンド
- typescript
- react
- react-router-dom
- react-cookie
- axios
- x-charts
- tailwindcss

デプロイ先
- フロントエンド vercel
- バックエンド render.com
- データベース nhost

今回の技術選定についてバックエンドのfastAPIは処理が高速なことや型定義を含められること、また自動ドキュメント生成により、コードベースでのドキュメントを作成することができることなどのメリットがあり選定しました。
フロントエンドはreactを使ってみたかっとことやtypescriptによるより安全に開発ができることから選定しました。
デプロイ先についてはフロントエンドではvercelが無料で使えてメジャーであることバックエンドではrender.comが格安で運用できること、データベースはnhostがpostgresqlをベースとして無料で使えるため選定しました。

# フロントエンドのコンポーネント、フォルダ構成設計
コンポーネント、フォルダ構成設計については下記の記事を参考にしました。
コンポーネント設計にはAtomicDesignがよく出てきますが、MoleculesとOrganismsでの境界がよくわからないという問題があるのとそこまで規模が大きくならないという理由からAtomicDesignは見送っております。

https://zenn.dev/overflow_offers/articles/20220523-component-design-best-practice

# フロントエンドのデザイン実装
figmaのデザインとフロントエンドのコンポーネント、フォルダ構成設計をもとにフォルダを分けをしデザインをtailwindcssを用いて実装しました。

# データベース論理設計
必要なデータを洗い出し、データベースを正規化しました。
![スクリーンショット 2024-06-10 113544.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538192/8a69516c-6c95-228b-685b-c689bda951a2.png)


# バックエンドのフォルダ構成設計
下記の記事を参考にしました。
service + repositoryで構築し各層で責務を分離することでスムーズに開発することができました。

https://medium.com/@kacperwlodarczyk/fast-api-repository-pattern-and-service-layer-dad43354f07a

# バックエンドAPIの実装
学習段階ではAPIのドキュメントを一通り見ていた程度だったので、基本的にはドキュメントやその他記事を参考にしながら実装していきました。
vscodeの拡張機能でpylanceでの型ヒントやpydanticによって型を意識したコーディングを行うことができました。
自動ドキュメント生成でスキーマを定義できることで実装前に入出力が何かを明確にでき、スムーズに開発することができました。

# バックエンドAPIをもとにフロントエンドの機能を実装
fastAPIで生成されるドキュメントをもとにAPIの入出力を確認しながら実装を行うことができた。reactをコンポーネント別で分けていたことで一つのファイルでコードの肥大化を防ぎ責務を分離した開発を行うことができた。

# バックエンド、フロントエンドをデプロイ
両サービスも簡単にデプロイすることができた。

# 最後に
始めてちゃんとした記事を書きましたが、アウトプットすると頭の中が整理できて良いですよ。これからも記事をアップしていきたい、、、
PostgreSQLで使えるデータ型の別表記

## 数値データ型

### 整数値

|別表記|本来の表記|解説|
|:--|:--|:--|
|int2|smallint|2バイトで表現可能な範囲の整数値<br>（-32768から+32767）|
|int4|integer|4バイトで表現可能な範囲の整数値<br>（-2147483648から+2147483647）|
|int8|bigint|8バイトで表現可能な範囲の整数値<br>（-9223372036854775808から+9223372036854775807）|
|serial2|smallserial|2バイトで表現可能な範囲の連番型|
|serial4|serial|4バイトで表現可能な範囲の連番型|
|serial8|bigserial|8バイトで表現可能な範囲の連番型|

### 浮動小数点数

|別表記|本来の表記|解説|
|:--|:--|:--|
|-|real|最低6桁の精度を持ち、1E-37から1E+37までの範囲|
|float|double precision|最低15桁の精度でおよそ1E-307から1E+308までの範囲|
|float4|-|最大9桁の10進数|
|float8|-|最大17桁の10進数|

## 参考

PostgreSQL v16 ドキュメントより
[8\.1\. 数値データ型](https://www.postgresql.jp/document/16/html/datatype-numeric.html)
Dataprocを使ったデータ処理基盤の構築と活用

## Dataprocとは
Google Cloud Dataprocは、HadoopやSparkを含むビッグデータツールをクラウド上で簡単にデプロイ、管理、スケールさせるためのマネージドサービスです。Dataprocを使用することで、複雑なクラスター管理やインフラストラクチャの設定を自動化し、迅速にビッグデータ解析を開始できます。

## 基本用語と機能の説明

### **Hadoop**
大規模データセットの分散処理を可能にするオープンソースフレームワーク。
  - **HDFS (Hadoop Distributed File System)**: データを分散して保存するファイルシステム。
  - **MapReduce**: データを並行して処理するプログラミングモデル。
  - **YARN (Yet Another Resource Negotiator)**: クラスターリソースの管理とスケジューリングを行うコンポーネント。

### **Spark**
Hadoopの分散処理能力をさらに強化し、インメモリ処理によって高速なデータ解析を実現するフレームワーク。
  - **Spark Core**: 分散データ処理の基本モジュール。
  - **Spark SQL**: 構造化データをSQLクエリで操作するモジュール。
  - **Spark Streaming**: リアルタイムデータストリーミングを処理するモジュール。
  - **MLlib**: 機械学習ライブラリ。
  - **GraphX**: グラフ処理ライブラリ。

## ユースケースと適用シナリオ

#### Hadoopのユースケース
- **大規模ログ分析**: 例えば、HDFSを使用して大量のログデータを保存し、MapReduceで並行処理します。
- **データウェアハウス**: 例えば、多数のソースからデータを収集し、分散ストレージに保存して分析します。

#### Sparkのユースケース
- **リアルタイムデータ処理**: 例えば、Spark Streamingを使用してリアルタイムのデータストリームを処理します。
- **機械学習**: 例えば、MLlibを使用して大規模データセットの機械学習モデルをトレーニングし、予測を行います。
- **インタラクティブデータ分析**: 例えば、Spark SQLを使用してデータを探索し、インタラクティブなクエリを実行します。

## 図解

#### Hadoopのデータ処理パイプライン
以下に、Hadoopを使用したデータ処理パイプラインの簡単な流れを図解します。

- データの読み込み: HDFSやクラウドストレージ（GCS）からデータを読み込みます。
- データの処理: MapReduceを使用してデータを並行処理します。
- データの変換: データを変換・解析します。
- データの出力: 処理結果をHDFSやクラウドストレージに保存します。

```plaintext
+---------------------+
|     Input Data      |
+---------------------+
          |
          v
+---------------------+
|     Map Phase       |
+---------------------+
          |
          v
+---------------------+
| Shuffle and Sort    |
+---------------------+
          |
          v
+---------------------+
|    Reduce Phase     |
+---------------------+
          |
          v
+---------------------+
|     Output Data     |
+---------------------+
```
#### Sparkのデータ処理パイプライン
以下に、Sparkを使用したデータ処理パイプラインの簡単な流れを図解します。

データの読み込み: HDFSやクラウドストレージ（GCS）からデータを読み込みます。
データの処理: Spark Coreを使用してデータを並行処理します。
データの変換: Spark SQLやMLlibを使用してデータを変換・解析します。
データの出力: 処理結果をHDFSやクラウドストレージに保存します。
```
+---------------------+
|     Input Data      |
+---------------------+
          |
          v
+---------------------+
|     Spark Core      |
+---------------------+
          |
          v
+---------------------+
|   Data Transform    |
| (Spark SQL / MLlib) |
+---------------------+
          |
          v
+---------------------+
|     Output Data     |
+---------------------+
```
## まとめ
Dataprocは、HadoopとSparkを用いたビッグデータ処理を容易にするクラウドマネージドサービスです。Hadoopは大規模なバッチ処理に適しており、Sparkは高速なインメモリ処理とリアルタイムデータ処理に適しています。それぞれの特徴とユースケースを理解し、適切なツールを選択することで、効率的なデータ処理基盤を構築できます。
Splunk お試しライセンスを使っていて失敗したこと

Splunk はお試しライセンスをFreeで一定期間使えるのですが、お試し期間が終わる前に、Freeライセンスに変更しておかないと、ライセンスバイオレーションとなり、それ以降はローリングウィンドウにバイオレーションがなくなるまで、サーチが使えなくなります。気をつけましょう〜
![スクリーンショット 2024-06-10 11.15.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51403/6c725b36-f3a6-c9a8-3b1b-3953e5fabd50.png)
使わせてもらえるのはありがたいですし、罰則もリーズナブルではありますが、一旦Splunkになれると（とは言っても１ヶ月くらいですが）いちいちSyslogに戻るのは耐えられない苦痛であります。
参考
https://docs.splunk.com/Documentation/Splunk/9.2.0/Admin/Aboutlicenseviolations?ref=hk
Microsoft認定資格はコスパが良い！

## 1. はじめに
最近、Microsoft認定資格を取得したので、資格のおすすめポイントなどを共有致します！
Cloud系の資格ではAWSなども有名ですが、個人で受験費用を負担する場合はマイクロソフト認定資格がおすすめです。

## 2. Microsoft認定資格とは
Microsoft社が認定する資格です。
[入門系（Fundamentals）](https://learn.microsoft.com/ja-jp/credentials/certifications/fundamentals)としては以下のような認定資格があります。

https://learn.microsoft.com/ja-jp/credentials/certifications/fundamentals

### AZ-900
Microsoft社が運営している**Azure全般**に関する入門資格です。
Azureでは数多くのサービスが存在していますが、各サービスに対する深い知識は不要です。
Cloudの概念と各サービスの簡単なユースケースが理解出来ていれば、十分合格できます。

### AI-900
**AzureのAI分野**に関する入門資格です。
AIに関する基礎知識、AzureのAI系サービスの簡単なユースケースが理解出来ていれば大丈夫です。
（私はAI初心者でしたが数日の学習で合格できました）

### DP-900
**Azureのデータ系分野**に関する入門資格です。
リレーショナルデータベースに関する知識なども必要となるため、非エンジニアは少し学習に苦労するかもしれませんが、入門資格なので難易度は高くないです。

### SC-900
**Azureのセキュリティ分野**に関する入門資格です。
※現在学習なので、あまり語れないです。。

上記以外にも、「Power Platform」や「M365」「D365」に関する入門系資格も存在しています。

## 3. なぜコスパが良いのか？
理由はズバリ **「資格維持費のコストが安いから」** です！

Microsoft認定資格を取得したい人は**Cloudに関する知識**を学びたい人が多いと思いますが、その場合は、AWSの認定資格なども有名です。
多くのベンダー資格は有効期限が設けられており、Microsoft認定資格・AWS認定資格も例に漏れず有効期限がありますが、Microsoft認定資格の場合は**資格更新費用が無料**です。

| 資格 | 有効期限 | 更新費用 |
|:-:|:-:|:-:|
| AWS認定資格 | 3年 | 再受験の費用が掛かる |
| Microsoft認定資格  | １年<br>※Fundamentalsは期限なし | **無料** |

:::note warn
**注意**
費用や有効期限は変更になることも多いです。
最新の情報は各ベンダーのサイトをご確認下さい。
:::

## 4. おススメの勉強法
私がおすすめするのは以下の学習方法です。

### 参考書を使う（AZ-900）
AZ-900の学習時、Azureに関する前提知識がない場合は、適当な参考書を購入して一通り読むのが良いです。
知識の定着化は後述の模擬テストで行えば良いので、この学習にはあまり時間を掛ける必要はありません。
ただし、AZ-900以外については極端に日本語の参考書が少ないのでご注意下さい。

### MicrosoftLeanを使う
Microsoftが運用する学習サービスです。
Microsoft認定資格の学習方法としては最もベターだと思います。
模擬テストもあるので、学習状況のチェックにも役立ちます。

https://learn.microsoft.com/ja-jp/training/browse/

### Udemyの問題集を購入する
学習自体はMicrosoftLeanで十分ですが、模擬テストの内容には偏りがあるので、Udemyなどの外部サービスの問題集を購入して学習状況のチェックをするのがおすすめです。
私はAZ-900の学習をしていた時、MicrosoftLeanの模擬テストは正答率95%でしたが、Udemyの模擬試験は75~85%ぐらいでした。本番では90%ぐらいだったので難易度としては二つの模擬テストの中間ぐらいの印象です。

## 5. オンライン試験（自宅）での注意点
私は試験をオンラインで自宅受験しましたが、トラブルが発生しないように共有しておきたい事があります。

https://www.microsoft.com/ja-jp/events/top/certification

### 受験スペースの確保
「ポスターや本棚はマスキング要」「手が届く範囲の物はどかす」など結構ルールが厳しいです。
当日受験できなくなったら一大事なので、他人の受験経験などをブログなどで調査した方が良いです。

私のおすすめとしては **「お風呂場受験」** です！
シャンプーなどの小物はバスタブの中に入れて蓋をするだけでOKです。

### 受験用アプリが固まる場合
私はAZ-900の受験時には問題なかったですが、AI-900の受験時には専用のアプリが固まるトラブルが発生しました。
アプリを起動したのち、マイク・カメラ・回線速度などのチェックが行われるのでですが、回線速度チェック後に「次へ」ボタンを押下したらアプリが固まってしまいました。
アプリを再起動したり、再ダウンロードしても事象は解消しなかったですが、**PC自体を再起動**したら事象が解消しました。

### ヘッドセットは外しましょう
ヘッドセットを着けて受験したところ、「外して手が届かない範囲に置く」よう指示されました。
注意点としては、事前の受験アプリセットアップ時にマイク設定などでヘッドセットを指定してしまっている場合は試験官と会話出来なくなり、アプリの再起動を求められます。
結構面倒なので、事前にヘッドセットは外してセットアップしておきましょう。

### チェックインは早めにしよう
受験用アプリのセットアップや本人確認書類・受験スペース画像のアップロードなど、チェックイン作業は何かと手間が掛かります。
受験時間の３０分前から作業が行えるので、早めに実施することをおすすめします。

### トラブルが発生しても焦らない
チェックイン作業でトラブルが発生した場合、受験開始時間に間に合わないという事もあると思いますが、多少遅れても大丈夫なようなので焦らないよう注意してください。
トラブルが発生した場合は、落ち着いて運営のカスタマーサポートに連絡しましょう。

### 試験途中、試験管からカメラの映像が見えないといわれた場合
私は試験中に掲題の事象が発生したことがあります。
試験管からは「本日は受験中止として、後日再試験とさせて欲しい」と案内頂きましたが、以下の方法を試験管に提案して実施したら正常に試験を継続することが出来ました。
- PCを再起動して受験アプリを再起動

ご参考にしてください。

## 5. 終わりに
私の体験談をまとめたものですが、少しでも皆様の学習の糧となれば幸いです。
冪等性の意味を勘違いしていた話

# はじめに
冪等性って同じ入力に対して常に同じ出力するっていう意味だと思ってたんですが、それは正確ではなく、同じ入力を何回しても状態が変わらないという意味でした。

つまり、以下は冪等性ではないです。
```javascript
function(a) {
    b += a; // bはなんかグローバルな値
    return a;
}
```

何回やってもaが返ってきますが、内部的にはbが変化してます。

以下が冪等性です。

```javascript
function(a) {
    b = a;
    return a;
}
```

というのが前提です。

# 冪等 is 何？
上記の勘違いを昔してて、最近ふとそもそも冪等ってなんやねん。冪なんて冪等以外で見たことないわって思ったので調べました。

そもそも「冪」というのは累乗の意味らしいです。言われてみたらべき乗っていう言葉は聞いたことありました。
冪しても等しい結果になる、つまり1を何回累乗しても1だよねっていう意味っぽいです。

さらに冪っていう時は覆うという意味があるらしく、確かに幕って漢字に冠がついてるのでなんかすごい覆う感出てますね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312001/f4b1483c-ce23-2dcc-ed97-1314de6ab1f0.png)
(https://www.kanjipedia.jp/kanji/0006240800 より引用)

さらにさらに冪冪（べきべき）っていう熟語があるらしく、「雲や塵 (ちり) などが一面におおうさま。」という意味があるので、使われてない物置に入った時に埃まみれになってたら是非「冪冪となってるな」って言ってみてください。きっと一目置かれます。（使い方あってるのか分かりませんが）

あとは冪等性は英語で**idempotent**と書きます。
語源的には、idemがsameでpotentがhaving powerっていうことらしいです。（参考 https://www.merriam-webster.com/dictionary/idempotent ）
idemは分かりませんが、potentはpotentialとかと同語源っぽいです。これで覚えました。

ちなみに、たまに使う[ケンブリッジ英英辞書](https://dictionary.cambridge.org)だと、idempotentの意味は、

> An idempotent element of a set does not change in value when multiplied by itself.

~~となってて、idempotentの説明にidempotent使うなよって思いました。（同サイトを馬鹿にする意図はありません。結構使わせてもらっててとてもわかりやすいので、むしろ好きです）~~

って思ったんですけど、idempotent elementっていうのはこういうものだよ。だからidempotentはこういうことだよって説明してるだけなんだと気づきました。ごめんなさい。

# まとめ
言葉って奥深いですね。
Todo作成時のフロー

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/6cb15145-c68e-e169-55f3-c0f8cbbb25ac.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/6709c4c6-fc02-9aae-45a7-36dcbc4c7387.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/bc29c3ba-db58-98f7-1376-34296fe6614b.png)


{!$Record.ActivityDate} +2

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/1b6969d0-9e69-75e7-0e52-e80db46a24b1.png)
ChatGPT の無償プランでどこまで GPTs が使えるのか検証してみた

# はじめに

2024年2月の記事で GPTs の使い方を紹介しました

https://qiita.com/RyoWakabayashi/items/74ced3fa9fe743b0c97d

その後、2024年5月に ChatGPT の無償プランでできることが増え、 GPTs も使えるようになりました

https://openai.com/index/gpt-4o-and-more-tools-to-chatgpt-free/

本記事では ChatGPT の有償プランで作成した GPTs を無償プランのユーザーから使用し、どのように見えるのか検証しています

## GPTs の作成制限

最も大きな違いは「GPTs を作成できるか」です

有償プランの場合、「+ 作成する」のボタンが活性（黒）になっています

![スクリーンショット 2024-06-10 11.07.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/6c5cc173-5594-945d-d1cf-2ae8ee446054.png)

無償プランの場合、「+ 作成する」のボタンが非活性（灰色）になっています

![スクリーンショット 2024-06-10 11.04.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/b067d3ec-fdd4-32b7-6ca8-0bb2d57ed6d4.png)

「+ 作成する」ボタンにマウスオーバーすると、有償契約するように案内が出ます

![スクリーンショット 2024-06-10 11.09.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/83cc692a-5119-7cdb-9dea-d83ca6800cb4.png)

## GPTs の機能制限

画像生成は実行できません

ファイルアップロード、データ分析、Web検索、知識（RAG）、アクション（API 連携）の機能は実行可能です

### 画像生成の実行例（実行不可）

画像生成機能のある GPTs を実行すると「画像の作成などには ChatGPT Plus をご利用ください」とメッセージが表示されます

![スクリーンショット 2024-06-10 11.16.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/8c51aa65-59ff-08bb-b028-eb70408d5541.png)

### ファイルアップロードの実行例

![スクリーンショット 2024-06-10 11.29.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/fd90d3df-6560-8b41-5f67-04ac6d48e301.png)

:::note warn
若く答えるように言ってあるのは秘密
:::

### データ分析の実行例

DALL-E による画像生成はできませんが、 Python で画像を作ることは可能です

![スクリーンショット 2024-06-10 11.26.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/5f6db569-c58e-e440-24d2-fb880a39567a.png)

Python で作った画像

![tsugaru_winter_palette.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/7a7f481c-8a5e-1b6a-4150-1f907f3e9072.png)

### Web検索の実行例

指定した Web サイトにタグを付ける実装例です
 
![スクリーンショット 2024-06-10 11.35.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/09410550-a1ee-9d67-20e6-d2124219096c.png)

### 知識（RAG）の実行例

大分市のWebサイトをHTMLとして知識に与えた実行例です

https://www.city.oita.oita.jp/o143/shitsumon/kankyo/1414464318254.html

![スクリーンショット 2024-06-10 12.55.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/d7da92c2-e121-44be-f187-b0e4e805eff6.png)

### アクション（API 連携）の実行例

アクションは実行可能です

ただし、有償/無償に関わらず確認メッセージが表示されます

![スクリーンショット 2024-06-09 15.14.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/b5302cdb-a493-b994-7353-01f2b04163c8.png)

![スクリーンショット 2024-06-10 11.23.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/1d572d95-9d88-a903-2e04-763a86d38bcc.png)

有償プランで GPTs のアクションを作る際、プライバシーポリシーの URL が入力必須になっています（以前はなかった項目）

## GPTs の利用量制限

GPTs で十数回チャットしていると、「GPT 使用の制限に達しました。」というメッセージが表示され、使えなくなります

![スクリーンショット 2024-06-09 15.20.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/18fbaf50-8022-b08a-9f93-e89f563a01e6.png)

あくまでもお試しと割り切りましょう

## まとめ

無償プランでも GPTs が使えるようになりましたが、機能や回数に制限があるため、本格的に使う場合は有償契約した方が良さそうです
CloudFlare Workers  AWSのRoute53で管理されている親ドメインのサブドメインを使う

## 概要

CloudFlare Workers & PagesでデプロイされているRemixのアプリケーションのドメインをRoute53で管理されている親ドメインのサブドメインで利用できるようにする。

## 前提

親ドメイン（miriwo.work）はお名前.comで購入後、DNSを自身のAWSのRoute53に変更している。
その親ドメインのサブドメイン（www.miriwo.work）をCloudFlare Wokers & Pagesでデプロイ中のアプリで使う。
HTTPS通信したい場合は親ドメイン、サブドメインにSSLの証明書が付与されていること。

## 方法

1. Workers & Pagesの当該アプリケーションの詳細ページに移動する。
1. 「カスタムドメイン」のタブを開く。
1. 「カスタムドメインを設定」をクリックする。

    ![概要___S_okawa_s-arcana_co_jp_s_Account___Cloudflare.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/5d219bcc-f33d-dc4c-4ef3-026992d45ff7.png)

1. 今回利用したいサブドメインを入力し「続行」をクリックする。

    ![概要___S_okawa_s-arcana_co_jp_s_Account___Cloudflare_と_Qiita.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/4ff8979f-d560-8e71-687c-5f77c6857efc.png)

1. 「自分のDNSプロバイダー」の「CNAMEセットアップを開始」をクリックする。

    ![概要___S_okawa_s-arcana_co_jp_s_Account___Cloudflare.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/381f8efb-5b37-f59b-174c-a0cf54b9fa6d.png)

1. Route53の親ドメインホストゾーンに「CNAMEレコード」を追加する。

    ![miriwo_work_-_レコードを追加.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/aade9d9a-7207-7e19-963b-32522df245f4.png)

1. 下記のように「アクティブ」になればここまでの設定は問題ないはずである。

    ![概要___S_okawa_s-arcana_co_jp_s_Account___Cloudflare.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/7ef0a342-2893-6b7a-2881-c03784ed3854.png)

1. あとは今登録したドメイン（今回なら https://www.miriwo.work ）にアクセスして問題なく画面が開くことを確認する。
【MySQL備忘】指定したマイナーバージョンへのアップデートインストールについて

## 目的
MySQLのバージョン8.0.28を**指定してインストール**したい

## OS
Red Hat Enterprise Linux 8.5

## 手順(15分程度)
### ①サイトから最新のリポジトリを確認しインストール
サイト:https://dev.mysql.com/downloads/repo/yum/
```
yum install -y https://dev.mysql.com/get/mysql80-community-release-el8-9.noarch.rpm(最新のものを取得)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3574230/5f44058e-e27a-8491-7109-cdab9685863b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3574230/ebf8d952-cad9-33c2-6d51-ca3812778a90.png)


### ②アーカイブサイトから必要なバージョン,OSのtarをダウンロード
アーカイブサイト:https://downloads.mysql.com/archives/community/

```
wget https://downloads.mysql.com/archives/get/p/23/file/mysql-8.0.28-1.el8.x86_64.rpm-bundle.tar(必要なバージョンを取得)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3574230/9420645b-9d15-b17c-a119-cb16327122fd.png)


### ③解凍
```
tar -xvf mysql-8.0.28-1.el8.x86_64.rpm-bundle.tar
```

### ④解凍後、中身を確認し必要なrpmファイルの名称を確認
```
mysql-community-client-8.0.28-1.el8.x86_64.rpm
mysql-community-libs-8.0.28-1.el8.x86_64.rpm
mysql-community-common-8.0.28-1.el8.x86_64.rpm
mysql-community-devel-8.0.28-1.el8.x86_64.rpm
mysql-community-server-8.0.28-1.el8.x86_64.rpm
```

### ⑤インストールの場合:localinstall を実行、アップデートの場合:localupdate を実行
１つ前の手順で確認したrpmファイルをインストール/アップデート
```
yum localinstall -y mysql-community-client-8.0.28-1.el8.x86_64.rpm mysql-community-common-8.0.28-1.el8.x86_64.rpm mysql-community-devel-8.0.28-1.el8.x86_64.rpm mysql-community-libs-8.0.28-1.el8.x86_64.rpm mysql-community-server-8.0.28-1.el8.x86_64.rpm
```

### ⑥再起動
mysql_upgrade -u root -p(更新の場合)
```
systemctl restart mysqld
```

### ⑦バージョン確認
```
mysqld --version
```

## 【補足】最新のバージョンにアップデートする場合

### サイトから最新のリポジトリを確認しインストール
サイト:https://dev.mysql.com/downloads/repo/yum/
```
yum install -y https://dev.mysql.com/get/mysql80-community-release-el8-9.noarch.rpm
```
### デフォルトのMySQLモジュールを無効化
```
yum module disable mysql
```

### MySQLのインストール
```
yum install -y mysql-community-server
```
(クライアントのみインストールの場合)
```
yum install -y mysql-community-client
```

### 再起動
```
systemctl restart mysqld
```

### バージョン確認
```
mysqld --version
```

### 補足の補足
MySQLのRDSに接続する場合のコマンド
```
mysql -u ユーザー名 -p -h RDSエンドポイント
```
C++ イベント駆動インターフェースの書き方

今更オブジェクト指向，今更C++ということではあるが，現在C++を強烈なオブジェクト指向言語として利用中．あくまで一例，tipsとして．コードは一番下にあります．


## テンプレの使用方法
Sampleを何かで置換してやるだけで動きます。
イベント関数の引数を変えたいときは`interface`の`OnSampleHandle`の引数，`SampleEventHandler`の`CallonSampleEventHandler`の実装で呼び出す部分の引数をそれぞれほしいものに変えればよいです。

イベントを作成したいときは，初めにEventHandlerを用意し，欲しいイベントのprivateリストを作成します。
続いて，欲しい関数を作成するか，または実装したいクラスにインターフェースを継承させます。関数を作成した場合は，その関数`f`を引数にして`SampleEventHandler::Instance()->addOnSampleEvent(f)`と登録してください。

イベントは，`SampleEventHandler::Instance()->CallonSampleEventHandler(vargs)`とすれば発火します。



## 解説
イベントハンドラの1つ目のリストは直接関数を，2つ目の関数はインターフェースの実装として登録する場合です。
直接関数は，関数をダイレクトにアタッチすることによって登録されます。この時，クラスのメンバ関数やstd::functionは禁止です。構造が異なります。

インターフェースの実装による登録は，テンプレ通りにすれば自動的に登録されます。ただし，少しオーバーヘッドがでかい恐れがあります。


本質はaddふにゃふにゃとCallon，vector2つなので，それらを内包させられる場合は一つのイベントハンドラで複数のイベントを管理できます。
これを利用して一つのイベントを複数のイベントに分解するなどの応用例があります。その場合は，Callon関数で自分の状態から適切な引数を与えるように呼び出せばよいです。

# interface
```c++
    typedef void (OnSampleHandle)(int var);
    class ISampleListener 
    {
    public:
        ISampleListener();
        virtual ~ISampleListener() = default;
        virtual void onFired(int var) = 0;

    private:
        void registerListener();
    };
```
## インターフェースの実装
```C++
    ISampleListener::ISampleListener()
    {
        this->registerListener();
    }

    void ISampleListener::registerListener()
    {
        SampleEventHandler::Instance()->addSampleListener(std::unique_ptr<std::remove_reference<decltype(*this)>::type>(this));
    }
```
# EventHandler
```C++
    class SampleEventHandler : public Singleton
    {
    public:
        SampleEventHandler();
        void CallonSampleEventHandler(int var);

        void addOnSampleEvent(OnSampleHandle event);
        void addSampleEvent(std::shared_ptr<ISampleListener> listener);
    private:
        v2 var;

        std::vector<ISampleListener*> _onSample = {};
        std::vector<std::shared_ptr<ISampleListener>> _onpSample = {};
    };

```
## ハンドラの実装
```c++
#include <omp.h>

    void SampleEventHandler::CallonSampleEventHandler(int var)
    {
        #pragma omp parallel for
        for (auto fn : this->_onSample)
        {
            fn(var);
        }
        #pragma omp parallel for
        for (auto p : this->_onpSample)
        {
            p->onFired(var);
        }
        }
    }
            void SampleEventHandler::addOnSampleEvent(OnSampleHandle event)
    {
        this->_onSample.push_back(event);
    }

    void SampleEventHandler::addSampleEvent(std::shared_ptr<ISampleListener> listener)
    {
        this->_onpSample.push_back(std::move(listener));
    }

```
ZED SDK のステレオカメラで欠損値の扱いを調査する。

## この記事で述べること
- 3Dカメラのdepthデータは計測点によって信頼度が異なる。
- そのため、信頼度の低い計測点を除外することが必要になる。
- 除外した点は欠損点となる。
- 欠損点の頻度を調整するパラメータがZED SDKに何があるか
- 欠損点を生じたときのデータはどのようになるか

## 想定する読者
stereolabsのzed2, zed mini, zed x などのステレオカメラの利用者
いまどきのステレオカメラは何ができるのかを知りたい人

## 前提
ZED SDK 4.1
Ubuntu 20.04
ZED2i
Python 版のAPI


## ZED SDKでの設定パラメータ

```
runtime_parameters = sl.RuntimeParameters()
(中略)
# 値を100にすると欠損値が少なくなる方向。値を小さくすると、欠損値が増える。
runtime_parameters.confidence_threshold = 1 ~ 100 の数値
runtime_parameters.enable_fill_mode = True or False
# 値を100にすると欠損値が少なくなる方向。値を小さくすると、欠損値が増える。
runtime_parameters.texture_confidence_threshold = 1 ~ 100の数値
runtime_parameters.remove_saturated_areas = True or False
(中略)
zed.grab(runtime_parameters)
```

## 他にも影響するパラメータ
init_params.depth_mode = depthの計算方式です。
init_params.depth_stabilization 
init_params.enable_right_side_measure = 物体の右側のエッジでのdepthを計算するかどうか

## 欠損値はどのように含まれるか
### depth_map
```.py:
zed = sl.Camera()
err = zed.open(init_params)
depth_map = sl.Mat()

zed.retrieve_measure(depth_map, sl.MEASURE.DEPTH)  # Retrieve depth
depth_map_data = depth_map.get_data()
H, W = depth_map_data.shape[:2]
count_isfinite = np.count_nonzero(np.isfinite(depth_map_data))
count_isnan = np.count_nonzero(np.isnan(depth_map_data))
count_isneginf = np.count_nonzero(np.isneginf(depth_map_data))
count_isposinf = np.count_nonzero(np.isposinf(depth_map_data))
```

このようにすることで、isfinte以外のデータである欠損値がどの程度の頻度で存在するのかを確認できます。

### 点群のZ成分
```.py:
zed.retrieve_measure(point_cloud, sl.MEASURE.XYZRGBA)
points = point_cloud.get_data()
print(f"{points.shape=}")

points_z = points[:, :, 2]
count_isfinite_points_z = np.count_nonzero(np.isfinite(points_z))
count_isnan_points_z = np.count_nonzero(np.isnan(points_z))
count_isneginf_points_z = np.count_nonzero(np.isneginf(points_z))
count_isposinf_points_z = np.count_nonzero(np.isposinf(points_z))

```

### 点群の色成分
```.py:
zed.retrieve_measure(point_cloud, sl.MEASURE.XYZRGBA)
points = point_cloud.get_data()
print(f"{points.shape=}")
assert depth_map_data.shape == points.shape[:2]
# 点群の最後の成分は色情報をfloat32にしたもの。
points_color = points[:, :, 3]
count_isfinite_points = np.count_nonzero(np.isfinite(points_color))
count_isnan_points = np.count_nonzero(np.isnan(points_color))
count_isneginf_points = np.count_nonzero(np.isneginf(points_color))
count_isposinf_points = np.count_nonzero(np.isposinf(points_color))
```

このような手法で、欠損値の状況を知ることができます。
[MAMP]MySQLが起動しなくなった

## 環境
MAMP: Version 4.5 (3208)
MySQL: 5.6.38

## 経緯
クエリログを確認したいからMySQL起動スクリプトを弄っていたらMySQLが起動しなくなった。バックアップを取っていたので戻しても起動しない。(Apacheは起動した)

## エラー
さっそくエラーログを確認。途中までは順調に行っていたが
`[ERROR] Fatal error: Illegal or unknown default time zone 'Asia/Tokyo'`が発生していた。

```terminal
// ~ 略 ~
2024-06-10 10:17:08 35673 [Note] Server hostname (bind-address): '*'; port: 3306
2024-06-10 10:17:08 35673 [Note] IPv6 is available.
2024-06-10 10:17:08 35673 [Note]   - '::' resolves to '::';
2024-06-10 10:17:08 35673 [Note] Server socket created on IP: '::'.
2024-06-10 10:17:08 35673 [ERROR] Fatal error: Illegal or unknown default time zone 'Asia/Tokyo' // ← ここ
240610 10:17:08 mysqld_safe mysqld from pid file /Applications/MAMP/tmp/mysql/mysql.pid ended
```

## 設定ファイル確認
設定を確認した。といってもいまの今まで動作していた設定項目なので正しく設定できているはず...

```my.cnf
[mysqld]
default-time-zone = 'Asia/Tokyo'
```

## 対応
雑ですが、ChatGPTに相談するとタイムゾーン周りは弄っていないことも含めて相談するとタイムゾーンが壊れているかもしれないから再構築しろと言われたので、一度MySQLを起動できるようにタイムゾーンの設定をコメントアウト

```my.cnf
[mysqld]
## default-time-zone = 'Asia/Tokyo'
```
MySQLを起動後、以下を実行
なんかめっちゃスキップされてそう。→ Warningだけ出力したパターンかな？

```terminal
mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p mysql


Warning: Unable to load '/usr/share/zoneinfo/+VERSION' as time zone. Skipping it.
Warning: Unable to load '/usr/share/zoneinfo/iso3166.tab' as time zone. Skipping it.
Warning: Unable to load '/usr/share/zoneinfo/leapseconds' as time zone. Skipping it.
Warning: Unable to load '/usr/share/zoneinfo/tzdata.zi' as time zone. Skipping it.
Warning: Unable to load '/usr/share/zoneinfo/zone.tab' as time zone. Skipping it.
```

MySQLを落とす → my.cnfのコメントアウトを解除 → MySQL起動

起動できた。
traffic editorで配置したモデルがgazeboで表示されない

# はじめに
　traffic editor で配置したモデルがgazeboで表示されない問題があったので投稿します。
　所々間違っている点があるかもしれませんが、ご了承ください。

# エラーの内容
　[youtube動画](https://www.youtube.com/watch?v=V-pzesxVJoA)に従って、以下のようにtraffic editorでマップを作成しました。
![スクリーンショット 2024-06-07 144434.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3810404/d1cadaad-f3a8-effa-11a1-17a8a98f0ecc.png)
　しかし、gazeboでマップを表示すると、カフェテーブルやソファのようなモデルが表示されませんでした。
![スクリーンショット 2024-06-07 144857.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3810404/4d693874-2569-84e3-8229-5d312203ee3e.png)
　エラーの内容は以下の通りでした。
```
Error Code 12 Msg: Unable to find uri[model://Sofa]
Error Code 12 Msg: Unable to find uri[model://Cafe table]
```
uriが見つからないみたいです。
# エラーの解決方法
　エラーの原因は二つありました。
- uriが間違っている。
- リンク先にモデルがそもそも無い。

　それぞれについて説明します。

 ## uriが間違っている
　最初にカフェテーブルが表示されない問題を解決します。
　ros2 runで生成されたworldファイルを見ると、先程のエラー文にあった通り、`<uri>model://Cafe table</uri>`となっています。
 ![スクリーンショット 2024-06-07 154652.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3810404/b5532f2a-4e4d-deed-5f0b-694ab1909cd6.png)
　一方この時、gazeboでinsertを開くと、二つのリンク先のモデルを参照している事がわかります。
 ![スクリーンショット 2024-06-07 163521.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3810404/6f2cd312-4646-2e8e-8a70-df63e027125b.png)
 その内、https\://models.gazebosim.org/のリストを見ると、cafe tableがあるので、クリックし一度gazeboで配置すると、/home/ubuntu/.gazebo/modelsでモデルのフォルダを参照できるようになります。
 ```
ubuntu@ubuntu2204:~$ cd /home/ubuntu/.gazebo/models
ubuntu@ubuntu2204:~/.gazebo/models$ ls -l
drwxrwxr-x 4 ubuntu ubuntu 4096  4月 24  2020 cafe_table
```
cafe_tableディレクトリの中のmodel.sdfを参照すると、uriが`Cafe table`でなく`cafe_table`である事がわかります。
　なので、worldファイルの
```
 <uri>model://Cafe table</uri>
```
 を
```
<uri>model://cafe_table</uri>
```
に変更します。
それでは、gazeboを立ち上げます。
![スクリーンショット 2024-06-07 163057.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3810404/7c784b68-6b7c-be64-f9e3-aa578ae72a28.png)
　カフェテーブルが表示されました。
```
Error Code 12 Msg: Unable to find uri[model://Sofa]
```
エラー文も減りました。

## リンク先にモデルがそもそも無い
　次にソファが表示されない問題を解決します。先程の二つのリンク先のモデルを調べると、ソファのモデルがそもそも無い事がわかります。無いモデルに関しては、以下のリンク先からダウンロードし、`/usr/share/gazebo-11/models`に配置します。
 https://app.gazebosim.org/dashboard
 　それではgazeboを立ち上げます。
 ![スクリーンショット 2024-06-07 171900.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3810404/70a43933-ad9a-6c94-103b-1ae6a32a0079.png)
 ソファも出現しました。エラー文も消えました。
【AWS備忘】SSM Change Calendar icsファイル取り込みによる祝日イベントの設定

## 目的
**icsファイルを取り込むことで数年分の祝日をAWSにイベントとして登録**することができた.
   
この記事ではその方法について解説する.

## 概要
Change Calenderでは,Googleカレンダー,iCalender,Outlook用のカレンダーの.icsファイル形式をインポートすることができる.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3574230/894211ba-7ed3-3813-7438-1ba289473008.png)
![clip-20230824160040.png](/knowledge/open.file/download?fileNo=3025)

outlookで日本の祝日のみ登録された.icsファイルを作成し,インポートする.

    
**outlookで追加される祝日一覧**
元日
成人の日
建国記念の日
天皇誕生日
春分の日
昭和の日
憲法記念日
みどりの日
こどもの日
海の日
山の日
敬老の日
秋分の日
スポーツの日
文化の日
勤労感謝の日
大晦日
(及び振替休日)



## 手順
※事情によりOutlookスクショは全てはありません
①outlookを起動する.

②ファイル/オプション/予定表/予定表オプション/予定表に祝日を追加:/日本を選択しOK→自分の予定表に祝日がインポートされる.

③自分の予定表/表示/ビューの変更/一覧/祝日を選択しコピーする.

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3574230/c9332bf1-65e4-986c-136b-dee86206313f.png)
    

    

④個人の予定表を右クリック/新しい予定表/任意の予定表の名前を入力しOK/表示/ビューの変更/一覧/コピーした祝日をペースト→同じ件数分祝日が追加される.
(②でインポートした日本の祝日のみが存在する予定表を作成する.)

⑤何年までの祝日が追加されているか確認する.

⑥新しい予定表を選択した状態/ファイル/予定表の保存→エクスプローラーが起動する.

    
⑦その他のオプション/期間を特定の期間に変更/開始日が当日,終了日を確認した年以降にして保存する.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3574230/629ed079-7220-a9a9-06e5-29a12a52aecd.png)
![clip-20230825104521.png](/knowledge/open.file/download?fileNo=3036)
   
⑧.icsファイルが作成される.

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3574230/d780b5e5-de7d-2c63-b59f-d8ffca330771.png)
![clip-20230825112541.png](/knowledge/open.file/download?fileNo=3038)
  

⑨AWSコンソールでchange calenderを開く.

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3574230/5a549342-7b89-3d06-14f4-ec8d34079f48.png)

⑩カレンダーを新規で作成or既存のものを編集する.
   
⑪作成した.icsファイルをインポートする.
   
⑫タイムゾーンをtokyoに変更する.
   
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3574230/06a10e37-ba1e-73fa-7434-9d822086aa21.png)
![clip-20230825112804.png](/knowledge/open.file/download?fileNo=3040)
   
⑬保存する.

⑭イベントが登録されたことを確認する.
   
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3574230/2c53521a-f6d6-71ac-9760-eb44ae3f07b9.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3574230/b9a71a2d-282e-5880-ff56-2bbfb0aaeac1.png)
![clip-20230825112847.png](/knowledge/open.file/download?fileNo=3041)
   
![clip-20230825112858.png](/knowledge/open.file/download?fileNo=3042)
    

(⑮振替休日が存在するので,不要なら削除する必要があります.)


終わり.
PhpSpreadsheetのgetCalculatedValue()で謎のFatal error(Formula Error)に遭遇

最近ExcelをPHPに読み込んであれやこれややることが多いのだが、その中でハマった話。

主要部分だけピックアップするとこんな感じのスクリプト。
```test.php
require('/lib/vendor/autoload.php');
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Reader\Xlsx as XlsxReader;
$file = '/var/www/file/test.xlsx';

$reader = new XlsxReader();
$spreadsheet = $reader -> load($file);
$worksheet = $spreadsheet -> getSheetByName('test');
echo $worksheet -> getCell('D60') -> getCalculatedValue();
```
こいつを走らせてみたところ
```
Fatal error: Uncaught PhpOffice\PhpSpreadsheet\Calculation\Exception: test!D60 -> test!F53 -> test!F52 -> test!F49 -> Formula Error: Unexpected , in /var/www/html/lib/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/Cell.php:295 Stack trace: #0 /var/www/html/test.php(81): PhpOffice\PhpSpreadsheet\Cell\Cell->getCalculatedValue() #1 {main} thrown in /var/www/html/lib/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/Cell.php on line 295
```
Formula Error＝式のエラー、ということらしいがExcel上では特にエラーが出ていない。

ちなみにD60のセルに入っているのはこんな式だった。
`=IF($C$4="",0,(VLOOKUP($C$4,$C$78:$T$101,14,0)*F53+VLOOKUP($C$4,$C$78:$T$101,15,0)*M53+VLOOKUP($C$4,$C$78:$T$101,16,0)*T53+VLOOKUP($C$4,$C$78:$T$101,17,0)*AA53)/VLOOKUP($C$4,$C$78:$T$101,18,0))`

Cell.phpの該当箇所を見たのだが
```Cell.php
public function getCalculatedValue(bool $resetLog = true)
{
 if ($this->dataType === DataType::TYPE_FORMULA) {
  try {
   $index = $this->getWorksheet()->getParent()->getActiveSheetIndex();
   $selected = $this->getWorksheet()->getSelectedCells();
   $result = Calculation::getInstance(
    $this->getWorksheet()->getParent()
   )->calculateCellValue($this, $resetLog);
   $this->getWorksheet()->setSelectedCells($selected);
   $this->getWorksheet()->getParent()->setActiveSheetIndex($index);
   //    We don't yet handle array returns
   if (is_array($result)) {
    while (is_array($result)) {
     $result = array_shift($result);
    }
   }
//以下略
```
と関数が定義してあるだけで要領を得ない。
色々ググってみたところ、[Yahoo!知恵袋](https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q11296529051)がヒット[^1]。

> getCalculatedValue()メソッドは通常、Excelのセルに記載された数式の計算結果を正しく取得します。しかし、一部の複雑な数式や特定の関数（例えば、VLOOKUPやINDIRECTなど）は、PhpSpreadsheetで正しく計算されない場合があります。
>これはPhpSpreadsheetの制限によるもので、解決策は限られています。(以下略)

ということらしい。まあ確かに複雑な式だということは認める。ともあれPhpSpreadsheetの限界ということならどうしようもないので、元のExcelのほうで該当するセルをコピー→値のみペースト、という姑息な[^2]手段で解決した。この場合```getCalculatedValue()```である必要はないので```getValue()```にスクリプトを変更して終わり。

[^1]:「AIからのお助け回答」なんてのが実装されてるんだな。知らなかった。
[^2]:本来の意味での「姑息」である。
ObsidianとChatGPTで数学ノートをLatexで簡単に取れるようになった件

# Obsidianは無限大

最近になりObsidianを使い始めたのですが快適に利用しています。以前はNotionを使っていたのですが、もっさりしているしフォーマットに項目いれるのも面倒だしモバイル版はさらにもっさりしているしであまり活用しきれませんでした。

一方でObsidianは基本がプレーンテキストなので肩の力を抜いてメモを取ることができ非常に重宝しています。

今回は数学ノートをObsidianで取り始めたのでその構成を備忘録代わりに書いてみようと思います。

# 数学ノートはLatexを使いたい。しかしLatexを書くのは面倒
一度でもLatexを使ったことがある人はわかると思うのですがLatexは非常に書きたく無いものだと思います。そのうえで、Latexを使うと非常に数式がきれいにかけることもまた同意いただけると思います。

簡単な数式を一個一個自分でLatexを使うのはいやだな。特に数学の勉強で、今は高校数学の復習をやっているのでなんども数式が出てきます。

# LatexはChatGPTに任せる
そこで考えたのがChatGPTに全部書いてもらう方法です。

画面構成は下記のようになっています。

![clipboard_image_75e90864ba1ce5fd.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379123/e4048c4f-e2d9-df70-5df3-dc5916cf7003.png)

必要なコミュニティプラグインはSurfingだけです。これはブラウジングをできるようにするプラグインです。
やることはただ単に右にChatGPTの画面をおいて、スクショ取った数式をLatexにしてくれって頼むだけです。

Obsidianは標準でLatexをサポート（$$で囲う記法のみだが）しているのでぺたぺた貼るだけで簡単にきれいなノートが取れる。

画像はコーシー・シュワルツの不等式がベクトルの内積と同じで、同様に相関係数が－1～1の範囲に収まることを説明できるといった内容です。

ほかにもThino（旧Memos）でTwitterライクなメモも出しています。

# デジタルノートでも数式を
今回はChatGPTとObsidian活用の一例として数学の勉強にも使えるといった内容を書きました。

## 蛇足 ChatGPTの数学理解力
数学の勉強中に出てきたわからない部分をそのままキャプチャしてこれこれがわからんと伝えたら答えを教えてくれたりもするので自分専用家庭教師としても一定の能力を感じてビビりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379123/f9c95c4b-864c-decc-9629-9b125e29b927.png)

これはどんどん人間の仕事が奪われるわけですわ。
現時点でのChatGPTのベストな使い方はこれだ！

## ChatGPTはこう使え！

2024年5月13日にGPT-4oがリリースされました。凄いことが起こったと、騒ぎ立てるようなメディアの記事もありますが、冷静に考えると、GPT-5が出たわけではありません。GPT-4のマイナーバージョンです。それでも、相当な機能が拡充されたようです。

今までOpenAIのサイトで無料で使えていたのは、GPT-3.5で、GPT-4を使うには、有償になっていました。そのため、仕方なくMicrosoft Copilotを使っていた人も多かったと思います。自分もその一人でした。

GPT-4oでは多くの人に門戸を広げてくれてます。OpenAIのサイトでGPT-4oが無料で使えるようになりました。5時間あたり10件までといった制限が付いてはいますが。それでも、時々、検索する分には充分でしょう。

GPT-4oが使えるように、設定を変更しないといけないといったことはありません。デフォルトのままで普通に使えば、GPT-4oで検索されます。ただし、制限を超えると、GPT-4oからGPT-3.5に自動で切り替わってしまいます。今、GPT-4oで動いているのかGPT-3.5で動いているのかは、確認できるようになっています。この機能はありがたいです。

Microsoft Copilotでは3月にGPT-4Turboが無償で使えるようになったばかりです。発表からまだ２か月しか経っていないのに、既に、GPT-4oが使えるようになっているのかと言えば、そこはまだ使えるようにはなっていないようです。ググっても、そのような発表記事は見当たりません。

CopilotではOpenAIのサイトのようにGPT-4とGPT-4Turboを切り替えて運用できるような設定はありません。知らないうちにGPT-4Turboを使っていたということになります。「おお、これがGPT-4Turboか、GPT-4よりも凄いな」と、体感することなくいつの間にか使っていたというのが実感でしょう。Copilotでも近い将来GPT-4oが使えるようになるだろうと思います。しかし、恐らく、まだしばらく先のような気がします。

現時点でのベストな使い方は、最初は、OpenAIのサイトを使ってGPT-4oの恩恵に授かり、利用制限を超えたら、Copilotを使って、GPT-4Turboの恩恵を受けるといった使い方が、ベストになりそうです。

## 更にプチ朗報！

エンジニアであれば、既にGithub copilotを使っている人は多いかと思います。残念ながら、Github copilotには無料版がありません。そんな恵まれた環境にない人は、ChatGPTを使ってコード生成をしていることかと思います。

そんな人にちょっとした朗報です。ChatGPTの無償版でもGPTsが部分的に利用できるようになっています。GPTsの中にCode Copilotといったアプリがあります。これがコーディングに特化したChatGPTアプリになっています。Github copilotによく似た性能を持っているものと想定されます。Github copilotが使える環境にない人は、ひとまずは、Code Copilotを使えばいいかと思います。

しかし、無料版ではCode Copilotも制限が付きます。制限の上限に達するとパタと使えなくなります。ChatGPT-3.5にバージョンダウンされるが使えるといったようにはなっていません。GPTsの機能そのものが使えなくなります。この点はご注意下さい。


> 注意
※この記事は、2024年6月10日時点での情報で書いています。