ChatGPTと一緒にする雑な開発

どうも、いつもAI様にお世話になっている人間のエンジニアです。
AI様は優秀なので愚かな人間の適当な指示でもそれなりに仕上げてくれます。

今回はAI様の素晴らしい仕事ぶりを皆様にご紹介します。

## バージョン

ChatGPT 3.5 Tubo

4の方が賢いらしいですけど遅いんであまり使わないです。

## Case A: とりあえず書いて

なんとなく構文覚えてるんだけど、イチから書くとしんどいやつを書いてもらいます。

### Swagger書いて

「OpenAPI3のコード書いて」と雑に聞いた時の回答です。

![スクリーンショット 2023-11-28 14.28.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184815/8557db2b-8771-55dc-9861-20f090ac7041.png)

なんとコピペしやすいようにコードCopyボタンが用意されています。
優しいですね。
なんか解説していますが欲しいのはコードなので無視します。


<details><summary>code</summary><div>

```yaml
openapi: 3.0.0
info:
  title: ToDoリストAPI
  version: 1.0.0
paths:
  /todos:
    get:
      summary: ToDoアイテムの一覧を取得
      responses:
        '200':
          description: 成功
          content:
            application/json:
              example:
                - id: 1
                  title: ショッピングリスト
                - id: 2
                  title: 会議の準備
    post:
      summary: 新しいToDoアイテムを作成
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                title:
                  type: string
              required:
                - title
      responses:
        '201':
          description: 作成成功
        '400':
          description: 不正なリクエスト
```
</div></details>

このままでもコピって使えるんですけど、もうちょい後付けで情報を足していきます。

今回はいかのような感じでお願いを追加していきました。

- 「エンドポイントを本の一覧を取得するようにして」
- 「検索ようのエンドポイントsearchを追加して」
- 「おやつたべたい」
- 「putとdelete足して」
- 「searchエンドポイント足して」
- 「ドメインはskynet.example.com」

<details><summary>code</summary><div>

```yaml
openapi: 3.0.0
info:
  title: 書籍API
  version: 1.0.0
servers:
  - url: https://skynet.example.com
paths:
  /books:
    get:
      summary: 本の一覧を取得
      responses:
        '200':
          description: 成功
          content:
            application/json:
              example:
                - id: 1
                  title: "ハリー・ポッターと賢者の石"
                  author: J.K. Rowling
                  publication_year: 1997
                - id: 2
                  title: "風の谷のナウシカ"
                  author: 宮崎駿
                  publication_year: 1982
                - id: 3
                  title: "1984年"
                  author: ジョージ・オーウェル
                  publication_year: 1949
  /books/{id}:
    get:
      summary: 特定の書籍を取得
      parameters:
        - name: id
          in: path
          description: 書籍のID
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: 成功
          content:
            application/json:
              example:
                id: 1
                title: "ハリー・ポッターと賢者の石"
                author: J.K. Rowling
                publication_year: 1997
    put:
      summary: 特定の書籍を更新
      parameters:
        - name: id
          in: path
          description: 書籍のID
          required: true
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                title:
                  type: string
                author:
                  type: string
                publication_year:
                  type: integer
              required:
                - title
                - author
                - publication_year
      responses:
        '200':
          description: 更新成功
        '404':
          description: 書籍が見つからない
    delete:
      summary: 特定の書籍を削除
      parameters:
        - name: id
          in: path
          description: 書籍のID
          required: true
          schema:
            type: integer
      responses:
        '204':
          description: 削除成功
        '404':
          description: 書籍が見つからない
  /search:
    get:
      summary: 書籍を検索
      parameters:
        - name: query
          in: query
          description: 検索クエリ
          required: true
          schema:
            type: string
      responses:
        '200':
          description: 成功
          content:
            application/json:
              example:
                - id: 1
                  title: "ハリー・ポッターと賢者の石"
                  author: J.K. Rowling
                  publication_year: 1997
```

</div></details>

人間なら最初に言えやとキレられそうなもんですが、ChatGPTさんはホモサピエンスより人間性がデキているので文句ひとつ言わずにそれなりに出力してくれます。

ちなみに2023/11/28現在OpenAPIの最新版は3.1ですが、学習データの都合上ChatGPTさんの中では3.0.0が最新みたいです。
まぁそんな変わらないんで新しい構文使いたい人はそこのところだけ差し替えましょう。

### プログラム書いて

「golangでhttpで取得したJSONデータをCSVに直してファイルに保存するコード書いて」
というとこんなものを描いてくれます。
ちょっとした作業ならこれでいいよね。

<details><summary>code</summary><div>

```golang
package main

import (
    "encoding/csv"
    "encoding/json"
    "fmt"
    "io/ioutil"
    "net/http"
    "os"
)

func main() {
    // JSONデータを取得するURLを指定
    url := "https://example.com/api/data"

    // HTTPリクエストを送信してJSONデータを取得
    response, err := http.Get(url)
    if err != nil {
        fmt.Println("HTTPリクエストエラー:", err)
        return
    }
    defer response.Body.Close()

    // JSONデータを読み取る
    body, err := ioutil.ReadAll(response.Body)
    if err != nil {
        fmt.Println("JSONデータの読み取りエラー:", err)
        return
    }

    // JSONデータを構造体にデコード
    var data []YourStruct // YourStructはJSONデータの構造体を表す型です
    if err := json.Unmarshal(body, &data); err != nil {
        fmt.Println("JSONデータのデコードエラー:", err)
        return
    }

    // CSVファイルにデータを書き込む
    outputFile, err := os.Create("data.csv")
    if err != nil {
        fmt.Println("CSVファイルの作成エラー:", err)
        return
    }
    defer outputFile.Close()

    csvWriter := csv.NewWriter(outputFile)
    defer csvWriter.Flush()

    // ヘッダー行を書き込む
    header := []string{"列1のヘッダー", "列2のヘッダー", "列3のヘッダー"} // 列のヘッダーを適切に置き換えてください
    if err := csvWriter.Write(header); err != nil {
        fmt.Println("CSVヘッダーの書き込みエラー:", err)
        return
    }

    // データ行を書き込む
    for _, item := range data {
        row := []string{item.Field1, item.Field2, item.Field3} // フィールドを適切に置き換えてください
        if err := csvWriter.Write(row); err != nil {
            fmt.Println("CSVデータの書き込みエラー:", err)
            return
        }
    }

    fmt.Println("CSVファイルが正常に作成されました。")
}

```

</div></details>

### 注意点

最新の情報に対応していないのと、たまに間違ったコードを書いてきます。
なのである程度出力には目を通してレビューしてから動かす必要があります。
「なんだかよくわからんけどヨシッ」はダメ絶対。

あと生成コードの著作権周りが微妙なので、プロダクトコードにあんまどでかいコードそのまま貼り付けるのは気をつけた方が良さそうです。
そこら辺は社内で合意取りましょう。

## Case B: なんやったっけ・・・

いろんな言語行ったり来たりしてると、基本構文やライブラリ名でもすっかり忘れます。
そういう時は莫大な記憶力をもつAI様に聞いてみましょう。

![スクリーンショット 2023-11-28 15.07.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184815/206d14f5-f314-1c13-66f1-66416b6cc77f.png)

リスト処理の構文本当に言語ごとにバラバラなんで困るんですよね。
やりたいことはわかっているのに構文出てこないことはまぁあります。

ググってもいいんですけどGPTに聞いたほうがコンパクトに答えが帰ってくるので愛用してます。
ちなみに自分はrubyなんもわからん人です。

## Case C: あるはず

知らんけどあるやろーできるやろー検索。
ライブラリとか探すとき用。
虚無から気配を察知するのはエンジニアの直感でやってください。
だいたいのもんはあります。

![スクリーンショット 2023-11-28 15.18.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184815/1df85972-88c4-971e-b2a0-fe20b333d538.png)

あることはあるが使えるかどうかは知らんので、公式ページやGitHub見に行ってから判断するのが良さげです。

## Case D: なんか考えてくれ

考えるのをやめた。
何も出てこないときに虚無から候補出してもらいましょう。

「技術ブログのネタ考えて」
「寄せ書きの内容考えて」
「彼女のプレゼント無難なやつ頼む」

![スクリーンショット 2023-11-28 15.34.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184815/15676ebe-8670-011e-0e6a-099158b5a305.png)

ばーっと一覧で候補で出してくれます。
そっからフィーリングで絞っていけばなんとかなるはず？
決められないあなたにおすすめ。

## おまけ

ChatGPT自体ではないんですがその周辺技術。

### Image To Text

Macのプレビューはデフォルトで文字認識機能が動作して、画像から文字をコピペできます。
めちゃくちゃお手軽で、スクショなどからさっとテキストとりだしてGoogleなりChatGPTに放り込める時代になりました。

iPhoneのカメラにも搭載されてて紙ベースならそっからコピーできます。
英語のよくわからない冊子出てきてもカメラかざして翻訳かければいいのでもう怖くない。

### Speech to Text

Chromeでその辺のプラグインが結構ありまして[これ](https://chrome.google.com/webstore/detail/voice-in-speech-to-text-d/pjnefijmagpdjfhhkpljicbbpicelgko)とか試してます。

ChatGPTの難点として文章で伝えないといけないので打つのだるいんですけど、その点音声なら楽です。
あとモバイル版のChatGPTアプリには音声認識がついてまして、ChatGPTさんと会話ができます。
壁打ちの会話で誰かを捕まえなくてもChatGPTが話聞いてくれるので良さげです。