【ChatGPTとすべてのProgrammerに捧ぐ】構造化プログラミング式プロンプト作成術

:::note info
本記事は、ChatGPT（無料版）で
行なっております。GPT4での確認
はできておりません。あしからず。
:::

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

　今回は、
　　ふとしたきっかけで
　　　知ったことを
　　　　報告させてください。

　まずは、こちらをご覧ください。
```Python:プロンプト
以下のテンプレート言語（jinja2ベース）のコードの意図を理解して結果を導いてください。
あなたが理解してくれることはわかっています。
なので、結果だけを出力してください。

{# Data #}
{% set people = [
  ('John', 25),
  ('Jane', 30),
  ('Bob', 15)
] %}

{# Process #}
| 名前 | 年齢 | ステータス |
|------|------|-----------|
{% for person in people %}
　| {{ person[0] }} 
　| {{ person[1] }} 
　| {% if person[1] >= 18 %}
　　成人
　{% else %}
　　未成年
　{% endif %} |
{% endfor %}
```
　これは、
　　ChatGPTさん用に
　　　記述したプロンプトです。

　結果は以下のようになります。

| 名前 | 年齢 | ステータス |
|------|------|-----------|
| John | 25 | 成人 |
| Jane | 30 | 成人 |
| Bob | 15 | 未成年 |

　説明すると、
　　データ部で、
　　　配列に、
　　　　三人の名前と年齢を
　　　　　セット。
　　処理部で、
　　　マークダウンのテーブル化。
　　　配列の一件ずつを出力。
　　　その人物が、
　　　　18歳以上なら、成人。
　　　　　　未満なら、未成年。
　　　　と、ステータスに出力する。

　という感じです。

　言っておきますが、
　　本当に動きますよw
***
　これは、
　　テンプレート言語と
　　　いうものを使っています。

　PythonやJavaScriptでweb開発を
　　されている方は、
　　　ご存知かもしれません。

　テンプレート言語に
　　ついての説明は、
　　　ウィキペディア
　　　「テンプレートエンジン」を
　　　　参照してください。

　テンプレートエンジンのひとつに、
　　jinja2があります。
　　　神社２です。
　　　　これも詳しくはウィキでね。

　ここで使ったのは、
　　Jinja2のサブセット、
　　　だと思ってください。
　　　　ChatGPTさんが
　　　　　教えてくれました。
***
　では、説明していきましょう。

　最初の日本語は、
　　ChatGPTさんに
　　　「読んで、意図を
　　　　理解して欲しい」という
　　　　　内容です。

　これがないと、動きません。
　解説モードに入ってしまいますw
　　しかも長い（汗）


　コードの方は、
　　なんとなく、
　　　わかるかと思います。

　まず、{# コメント #}です。
　　説明不要ですね。

　{% 構文 %}が、処理になります。

　その「構文」は以下のとおり。

　変数の初期化は、set文。
　　数値は、　数値そのまま。
　　文字列は、「'」文字列「'」。
　　　　　　　「"」文字列「"」。
　　配列の初期化は、
　　　　　　　「set 変数名 = []」。

　制御には、
　　if文、elif文、else文、
　　　for文、while文が
　　　　使えます。

　制御の終わりには、
　　「end制御文」です。
　　　カッコ閉じですね。

　条件式は以下のとおり
　　比較演算子：
　　　`==`：等しい
　　　`!=`：等しくない
　　　`<`：より小さい
　　　`>`：より大きい
　　　`<=`：以下
　　　`>=`：以上

　　論理演算子：
　　　`and`：論理積
　　　`or`：論理和
　　　`not`：否定

```Python:例
{% set a = 5 %}
{% set b = 10 %}

{% if a == 5 %}
  aは5です。
{% endif %}

{% if a < b and b > 0 %}
  aはbより小さく、かつbは0より大きいです。
{% endif %}

{% if a != 0 or b != 0 %}
  aかbは0ではありません。
{% endif %}

{% if not (a > 10) %}
  aは10より大きくありません。
{% endif %}
```
　配列の形は、以下の三つがあります。
　　・辞書型
　　　（変数名とデータで
　　　　　ワンセット）
　　・インデックス型
　　　（カッコでワンセット）
　　・分割型
　　　（名前の配列、年齢の配列）


　インデントは、
　　特に必要ではない、と思います。
　　　半角スペースでも
　　　　全角スペースでもOK。
　　　　　見た目ですw

　よく見ると、
　　「成人」とか「未成年」とか
　　　直に書かれています。
　　　　これそのまま、出力です。

　　出力には、
　　　「{{ name }}は{{ age }}歳」
　　　　と、変数名を指定しての
　　　　　出力も可能です。

　で、
　　**ChatGPTでの注意点
　　　jinja2のサブセットである。
　　　以下の４点はサポートなし
　　　・インクルード
　　　・演算（場合による）
　　　・関数（またはマクロ）
　　　・input文（手入力）**

　　　**文字列操作は、
　　　　信用できません。**

　最後の「信用できない」、
　　というのは、
[【ChatGPT】文字数数えさせたらダメだった](https://qiita.com/kabumira/items/f50e10e3655d0bd5cfb5 "【ChatGPT】文字数数えさせたらダメだった")
　　で、試した結果ですが、ダメ。

　このテンプレート言語でも
　　「{{ message | length }}」
　　　とmessageの長さを
　　　　求めたのですが、
　　　　　数が定まらない。

　まぁ、ChatGPTさんが、
　　このテンプレート言語を
　　　エミュレートしているから
　　　　**ダメでもともと**、
　　　　　と諦めています。

　でも、
　　ループのカウンターは、
　　　カウントアップして、
　　　　繰り返しているので、
　　　　　その程度は、大丈夫。

　その一例をあげると
```Python:ひとつの例（プロンプト）
以下のテンプレート言語（jinja2ベース）のコードの意図を理解して結果を導いてください。
あなたが理解してくれることはわかっています。
なので、結果だけを出力してください。

{# Process #}
{% set count = 0 %}

条件を満たすまで繰り返します：
{% while count < 5 %}
- カウント: {{ count }}
{% set count = count + 1 %}
{% endwhile %}
{# Process end #}
```
　結果は
>条件を満たすまで繰り返します：
>- カウント: 0
>- カウント: 1
>- カウント: 2
>- カウント: 3
>- カウント: 4

　このとおり。
　このあと、説明が続きますけどw
***
　このテンプレート言語を
　　教えてくれたのは、
　　　もちろんChatGPTさんです。

　このテンプレート言語についての
　　質問は、ChatGPTさんに
　　　お尋ねください。

　上記のプロンプトを
　　実行してからの質問が
　　　良いと思います。

　そうすれば、
　　ChatGPTさんが、
　　　こちらが必要とする情報が、
　　　　テンプレート言語のことだと
　　　　　認識してくれます。

　あっ、
　　ここまで出したプロンプトは、
　　　最初の日本語部分以外は、
　　　　ほぼChatGPTさん記述です。
　　　　　コメントとインデントが
　　　　　　自分です。

　　指示を出して、
　　　記述してもらいました。
***
　同じプロンプトを
　　GoogleBardと
　　　MicrosoftBingにしてみた。

　Bardも処理できるけど、
　　マークダウン記法に
　　　対応していない。
　Bingは、
　　きちんと
　　　マークダウン記法に
　　　　対応しています。
***
　ここまで
　　書いておいてなんですが、
　　　使いみちが、わからない。

　テーブルやら箇条書きやらに
　　使えるだろうとは、わかるのよ。

　でも、
　　わざわざChatGPTを
　　　使ってやることでもない
　　　　と思うのです。

　テスト的に、
　　サンプルデータが欲しいなら
　　　CSV形式で出してもらって、
　　　　使えばいいだけだし。

　あっ、
　　トークンは
　　　削減できそうですね。
　　　　日本語が確実に
　　　　　少なくなりますから。

　あとは、名前かしら？
　　「kabumira式プロンプト」
　　　ということで。

　あっ、書いてみただけですのでw
***
　それから、追記しました。
　　フィルターについてです。
[【ChatGPT】構造化プログラミング式プロンプトの追記（フィルター編）](https://qiita.com/kabumira/items/b13f6b43c0ce6cb45825 "【ChatGPT】構造化プログラミング式プロンプトの追記（フィルター編）")

***
なお、英語版ですが、
　詳細は、
　　jinjaのドキュメント参照してね。
[Template Designer Documentation — Jinja Documentation (3.1.x)](https://jinja.palletsprojects.com/en/3.1.x/templates/?highlight=safe#jinja-filters.abs "Template Designer Documentation — Jinja Documentation (3.1.x)")
***
　追伸。
　日本語部分を
　　DeepLで英語にして、
　　　実行してみたら
　　　　動いた！
```Python:先頭のプロンプト（英語版）
Please understand the intent of the following template language (based on jinja2) code to guide your results.
I know you will understand.
So, please output only the results.

{# Data #}
{% set people = [
  ('John', 25),
  ('Jane', 30),
  ('Bob', 15)
] %}

{# Process #}
| 名前 | 年齢 | ステータス |
|------|------|-----------|
{% for person in people %}
　| {{ person[0] }} 
　| {{ person[1] }} 
　| {% if person[1] >= 18 %}
　　成人
　{% else %}
　　未成年
　{% endif %} |
{% endfor %}
``