プログラマのためのChatGPT活用 - コーディング編 -

# この記事について

爆発的な話題となっているChatGPTですが、そのあまりのシンプルさ、適用範囲の広さ、活用方法の多彩さから、その能力を十分に引き出すことはなかなか難しいものです。ChatGPTはソフトウェア開発の多くのプロセスに活用できますが、この記事ではコーディングフェーズでの活用についてまとめます。

応答は長い物が多いので、基本的に記載しません。ぜひChatGPTに入力してみてください。

# ChatGPTの使い方に関するコツ

 - 背景や前提を十分に伝える。
ChatGPTに質問の背景や前提を伝えることでより精度の高い結果が返ります。「このプログラムは〜を目的としたものの一部です。何をしているか説明してください。」のように質問に背景・前提を付け足すこと重要になることがあります。応答の精度が低いと感じた場合は、こういった前提条件などを付加して何度も質問してみましょう。

 - スレッド内では文脈を活用してシンプルに質問する。
「下記のコードをRustに書き直して」　と質問した後に 「Javaの場合は？」 のように質問しても文脈からChatGPTに何を求めているか判断してくれるので、同種の内容のバリエーションを要求したい場合は入力の手間を省くことができます。ChatGPTは日本語でだいたい8000文字程度の過去の対話を記憶しています。

 - 公式ガイドを読む
うまくChatGPTを扱うための詳しい公式情報が存在します。参考文献に記載しますので、時間のある方は読んでみてください。

# 活用例

## 簡単なユーティリティやアルゴリズムをコーディングしてもらう

ちょっとしたユーティリティやアルゴリズムなど、小さく依存のない処理であれば、仕様を伝えることで丸ごとコーディングをお願いすることができます。

```
JavaでList型のパラメータを受け取り、先頭が"A_"または"B_"で始まる要素だけを返す関数を作成して。
```

## 既存のコードを高速化やリファクタリングしてもらう

間違ったコードを生成してしまうこともあるの注意が必要ですが、なぜした方が良いかという説明も出力してくれますので、そのアイディアを参考にすることができます。

```
下記の〜言語のコードを高速化してください。

Code:"""
コードを貼る
"""
```

```
下記の〜言語のコードをリファクタリングしてください。

Code:"""
コードを貼る
"""

```

## 既存のコードを別の言語で書き直す

ChatGPTは主要なほとんどの言語で別の言語への書き直しができます。アセンブラやWebAssemblyに変換することもできます。

```
下記のJavaコードをRubyで書き直して。

Code: """
List<String> filteredList = new ArrayList<>();
for (String element : list) {
    if (element.startsWith("A_") || element.startsWith("B_")) {
        filteredList.add(element);
    }
}
return filteredList;
"""
```

## コードの内容を説明してもらう

プログラムが何をしているか説明してもらうことができます。ChatGPTはコードについての背景をなるべく教えてあげることで精度を上げることができます。全体として何を目的としたプログラムのコードであるかなど。

```
下記はPyTorchを使ったPythonのコードです。何をしているか説明してください。

Code: """
for epoch in range(20):
    running_loss = 0.0
    for i, data in enumerate(train_loader, 0):
        inputs, labels = data
        optimizer.zero_grad()
        outputs = model(inputs.float()/255.0)
        loss = criterion(outputs, labels.view(-1,1).float())
        loss.backward()
        optimizer.step()
        running_loss += loss.item()
"""
```

## ライブラリの使い方や落とし穴について教えてもらう

```
ReactのuseEffect()の使い方と落とし穴を教えて。
```

## HTMLやJSXのテンプレートを出力してもらう

### HTMLの例

```
チャット用のメッセージ入力UIとして適切なHTMLとCSSを出力して。アイコンにはfont awesomeを使って欲しい。
```

### JSX(Styled Component)の例

```
チャット用のメッセージ入力UIとして適切なJSXと適切に分割されたStyled Componentを出力して。アイコンにはfont awesomeを使って欲しい。
```

## DSLのパーサーを書いてもらう

ChatGPTはBNFを解釈してくれます。BNFと言語を指定してパーサーを出力させることで、簡単なDSLを素早く作ることができます。

```
下記はドメイン固有言語の構文を表すBNFです。この言語のパーサーをTypeScriptで実装してください。

BNF: """
<additive-expression> ::= <multiplicative-expression>
                        | <additive-expression> + <multiplicative-expression>
                        | <additive-expression> - <multiplicative-expression>
<multiplicative-expression> ::= <primary-expression>
                              | <multiplicative-expression> * <cast-expression>
                              | <multiplicative-expression> / <cast-expression>
                              | <multiplicative-expression> % <cast-expression>
<primary-expression> ::= <identifier> | <constant>
"""
```

## SQLを書いてもらう

ChatGPTはデータベースのスキーマを理解してSQLを書いてくれます。JOINもできますし、英和のマッピングやコメントなども考慮してくれるので、自然な質問ができます。

```
下記のデータベーススキーマがあります。この時、名前が"山田"で始まる人のうち、年齢が30歳以上のアカウントの好きなエディターを抜き出すSQLを書いてください。

Schema: """
CREATE TABLE account(
    id INTEGER,
    attr1 INTEGER NOT NULL,
    /* 好きなエディター */
    attr2 VARCHAR(255) NOT NULL,
);

CREATE TABLE profile(
    account_id INTEGER,
    name varchar(255),
    age integer,
    constraint fk_person_id foreign key(person_id) references account(id)
);
"""
```

## Linuxコマンドを書いてもらう

パイプや複雑なオプションを使って要望を叶えるLinuxコマンドを出力してくれます。初心者は相当助かるのではないでしょうか。また、「別の方法はある？」のように聞いて複数の解法を引き出すこともできます。ベテランの方もより効率的な解法を見つけるのに役立ちます。

```
ディレクトリhogeから再帰的に拡張子が".txt"と".js"のファイルを検索して、"foo"から始まる行のみを出力するLinuxコマンドを書いてください。
```

出力例:

```
以下のコマンドを使用することで、要件を満たすことができます。

find hoge/ -name "*.txt" -o -name "*.js" -print | xargs grep "^foo"
このコマンドは、以下のように動作します。

find hoge/ で hoge ディレクトリから再帰的に検索します。
-name "*.txt" -o -name "*.js" で、拡張子が ".txt" または ".js" のファイルを検索します。
-print で、検索結果を標準出力に表示します。
標準出力を xargs で grep にパイプします。
grep "^foo" で、"foo" から始まる行だけを抽出します。
```

## 仕様書上のリストや表などをプログラムコードに整形する

### Mapに整形する

```
下記の表のNameとDescriptionをScalaのMapにして。

CSV: """
Name,Description
Hoge,これはHogeです
Fuga,これはFugaです
"""
```

### Scalaのcase class(他言語の構造体のようなもの)に整形する

```
Scalaで下記の表に適切なcase classを定義してSeq型に詰めて。

CSV: """
Name,Description
Hoge,これはHogeです
Fuga,これはFugaです
"""
```

## エラーについて教えてもらう

一般的なエラーについては原因や解決方法を教えてくれます。良い回答が得られない場合は、どういった目的で何をしようとしたのか、エラーが発生したコードなどを提示して再度聞くと良い回答が得られる場合があります。

```
下記のエラーが出ました。どうすればいいですか？

Error: """
"(<class 'RuntimeError'>, RuntimeError('Given groups=1, weight of size [32, 3, 3, 3], expected input[11, 4, 512, 512] to have 3 channels, but got 4 channels instead'), <traceback object at 0x11db1bfc0>)"
"""
```

## コードにコメントを付加してもらう

```
下記のTypeScriptのコードにコメントを付加してください。

Code: """
<<ソースコードを貼る>>
"""
```

## 変数名や関数名を考えてもらう

```
TypeScript言語で、課金ガチャを回しすぎてお金がなくなって困っている人であるか判定する関数の名前の候補を５個考えて。
```

応答例

```
isGachaSpendingTooMuch
hasGachaBudgetRunOut
isGachaExpenditureExcessive
hasGachaFundsDepleted
isGachaFinancialStrain
```

## ダミーデータを作ってもらう

```
日本人の名前をフルネーム(漢字)で適当に5個考えて。名字と名前はカンマで区切って。リストで表示して。
```

応答例

```
佐藤, 美智子
田中, 淳一
中村, 歩
山本, 一雄
石川, 恵美子
```

## コードレビューしてもらう

プログラム言語だけでなくSCSSやHTMLなどマイナーな言語でなければほぼ対応してくれます。

```
下記のTypeScriptのコードについて、問題や改善すべき点がありますか？

Code: """
<<ソースコードを貼る>>
"""
```

## テストを書いてもらう

```
下記のTypeScriptの関数に対するjestを使ったテストコードを出力してください。

Code: """
type Person = {
  name: string;
  age: number;
};

function isArasa(person: Person): boolean {
  return person.age >= 28 && person.age <= 32;
}
"""
```

# テクニック

## コーディング規約を与える

ChatGPTが文脈を理解する特性を活かして、事前にコーディング規約を与えておくことで使いやすいコードを生成させることができます。シンプルなルールの羅列にし、念押しの文章などを入れると指定通りの結果が得られやすいです。

1回めの入力で文脈を与える：

```
今後の回答は下記の文脈に従って行なってください。

Context: """
TypeScriptでプログラミングしてください。

下記のコーディング規則に従ってください。
 - 型アノテーションはすべてanyにしてください。他の型は使用禁止です。
 - 関数名は全てsnake caseを使ってください。
 - 変数名は全てsnake caseを使ってください。

可能な限りコーディング規則に従ってください。
"""
```

２回目以降で具体的な指示：

```
下記の関数を実装してください。
1. １つの文字列を受け取って、文字列内にある数値を正規表現を使って抜き出します。
2. 抜き出した数値をnumber型に変換します。
3. もっとも大きい数値を関数の返り値とします。
```

# 便利ツール

### VSCodeプラグイン

VSCode上で選択したソースコードに対してテストの生成や解説、コメントの追加を実行してくれるプラグインです。
[詳しい解説記事](https://qiita.com/tak001/items/c3000b3ce9b6e72b2ae5)があるので見ていただくと設定方法などがわかります。

### shell_gpt

GPTのAPIを読んでくれるCLIツールです。Linuxコマンドを生成して実行する機能を備えています。
https://github.com/TheR1D/shell_gpt


## その他のChatGPT関連記事

https://qiita.com/devneko/items/4b3bc01cfa4439bfa36f

https://qiita.com/devneko/items/7621ee3803105d2bf3d3

# AI時代のソフトウェア開発に関するコミュニティ

 - [AI駆動開発Discord](https://discord.gg/38tZ5yrsK6) : AIを使ったソフトウェア開発について共有するコミュニティ

# 参考文献

 - [Official - Prompt design](https://platform.openai.com/docs/guides/completion/prompt-design)
 - [Official - Best practices for prompt engineering with OpenAI API](https://help.openai.com/en/articles/6654000-best-practices-for-prompt-engineering-with-openai-api)
 - [Official - Techniques to improve reliability
](https://github.com/openai/openai-cookbook/blob/main/techniques_to_improve_reliability.md)