🐷

ChatGPTを用いたノーコードプログラム作成例

2023/04/06に公開

本記事の目的

Pythonの自学自習でChatGPTを使っているのですが、プログラムによって何を実施したいのかさえ記載すれば、プログラムを簡単に実装可能であると実感しています。しかしながら、ミスなく要件を満たすコーディングをするためには。実際のコーディングを決定する質問文の設定が場合によっては難しかったり、回答コードにエラーが出てしまった際にどのような追記質問をすべきかを考える上で、ChatGPTに対する慣れやコーディングに対する素養もある程度必要になる場合もあります。したがって、コーディングという面において、初心者がChatGPTを利用すれば必ず時間削減になると現状は言えないと考えています。そこで、事前にChatGPTを用いて出力したコード情報を活用し、どのような質問文が良いか修正したりエラーが出た際にも今までの履歴を参考にしたりして、システム内部で勝手に修正し、ChatGPTに質問し直すということができれば、コードを1文を書いたことのない初心者が、より使いやすいノーコードのシステムが構築できるのではないかと考えています。
 本記事では、そのための最初のステップとして、ChatGPTのAPIでコーディングをする方法を学習し実装していきたいと思います。

実装環境

Google Colaboratory

ChatGPTを用いたコーディング時間を削減する方法

ChatGPTを用いたコーディング時間を削減する方法を以下のSTEPで実装できると考えています。
実装手順
 まず、コーディング実施内容を読み取ります。これは以下のように、何を実施したいのかを記載した情報で、今回はテキストファイルに保存した情報を読み取ります。
実装例1
 次に、上記コーディング内容に対して自然言語処理のモデル等を利用し、類似性を図る等、以前コーディングした情報と比較し、実施したいコーディングが既にないかを判断します。もしあればChatGPTを回さずにそのコーディングを呼び出し、作業時間の削減やChatGPTのAPI使用によるコスト削減が可能になります。

上記自然言語モデルの分類結果で、既にコーディングしたものがないと判断された場合、ChatGPTに読み込ませるコーディング実施内容の修正や要約をします。ChatGPTを用いたコーディングにおいて重要な点は、質問文章の調整です。前回質問内容(前回回答のプログラム)を使いつつ、修正依頼をかければ上手くいくこともありますが、最初に与えるコーディング実施内容を分かりやすく書けば、1回のやり取りで上手くいきます。つまり、文章の要約や修正可能なシステムを構築することにより、ChatGPTでのやり取りを少なくできます。
 修正した質問に対し、ChatGPTでのコーディングを実施し、出力されたコーディングの結果を試してよいプログラムであれば、コーディング実施内容、実際のコーディング、評価を保存していきます、
 続いて、ChatGPTのAPIを用いたコーディングの実装方法を学習していきます。なお今回実装する言語はExcelで用いられているVBAとします。

ChatGPTのAPIキーの取得方法

ChatGPTのAPIを使用するためには、課金設定とAPIキーの取得をする必要があります。APIキーは、こちらのサイトにログインして取得可能です。
 課金設定とAPIキー取得手順は他の方がまとめているので、そちらを参考にしてください。

ChatGPTのAPIを用いたコーディングの実装方法

まず、openaiライブラリをインストールします。

!pip install openai

続いて、APIキーの保存をします。”sk-xxx”に各個人のAPIキーを記載します。

openai_API.py
import os

#APIキー保存
os.environ["OPENAI_API_KEY"] = "sk-xxxx"
openai.api_key = os.environ["OPENAI_API_KEY"]

次に、プログラミングの実装内容を格納します。なお、人にとって改行したり空白文字を付けたりすると考え、ファイル内容を正規化しています。  
 ChatGPTを使ったコードの修正質問をしていると、どこの部分を修正すればよいのか、各コードの意味について理解しにくい部分があると個人的に感じています。もちろん前後の文脈もあり説明していない部分もあるとは思いますが、可能な限り初心者向けにしたいと考えました。そこで、コメント文については初心者向けになるように予め記載しておきました。

program.py
import re

#ファイルパス
file_path = "/content/program1.txt"
#コーディング実施内容の保存
program_txt = "" #program_txt : 実装内容格納テキスト
with open(file_path,"r") as f :
  #空白、タブ、改行の除去
  program = re.sub(r'[\s\t\n]','',f.read())
  #テキストの保存
  program_txt += program

program_txt += "上記に対して、VBAでプログラムコードとコメント文のみを書いて。" + \
              "コメント文は初心者向けに詳細に書いて"

では、実際のコーディング実行部分の実装に移ります。なお、コードはこちら公式ドキュメントを参考にしました。

ChatGPT_coding.py
import openai

count = 1
code_judge = False
repair_txt = "修正して。" + \
             "初心者向けにコメント文も詳細に書いて"
before_program_txt = ""
apply_program = ""

while not code_judge :
  
  if count == 1 :
    #CHATGPT 初回
    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages=[
            {"role": "user", "content": program_txt},
            ],
        )

  else :
    #CHATGPT 2回目以降
    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages=[
            {"role": "user", "content": program_txt}, #質問内容
            {"role": "assistant", "content": before_program_txt},#前回までの文脈
            {"role": "user", "content": repair_txt},#追加質問文
            ],
        )

  #前回プログラムの格納
  before_program_txt += str(count) + "回目は以下のプログラムの回答あり。\n" + response.choices[0]["message"]["content"] + "\n"
  print(before_program_txt)
  #採用プログラム
  apply_program = response.choices[0]["message"]["content"]
  print("採用プログラム")
  print(apply_program)

  count += 1

  input_str = input("このプログラムで良い場合は 'y'  を入力してください。良くない場合は適当な文字を入力してください。")
  if input_str == 'y' :
    code_judge = True
  else :
    #追加のコメントを書きたい場合は追記要望として付けくわえます。
    add_str = input("上記プログラムに対して、何かコメントがあれば記載してください")
    before_program_txt += add_str + "\n"
  

今回はprint文でコードが出力するようにしたので、そのコードをマニュアルでコピーしてExcelのマクロにそのまま貼り付けて動くかでプログラムの評価をしました。
 回答されたプログラム内容は、全て前回文脈を示す” before_program_txt”に保存しており、質問すればするほど文章が増え、トークンが使用上限(4096トークン)に達してしまう場合があります。使用上限に達すると以下のようなエラーが出て質問が消えてしまうので、この部分は改善の余地が大いにあると感じています。
使用上限エラー

評価

今回は、以下の2つのプログラムをコーディングしていきます。
実装例1
実装例2

  • 実装例1 : 列3つに値が格納されており、各行の最大値と平均を出力。また、各列の最大値と最小値に対して、各々色付けを実施。
  • 実装例2 : 日付毎の数値の推移があるので、その推移を折れ線グラフで描画。

実装例1

実装例1では2回プログラムを書き直させてみました。内容は以下の通りです。

ex1_1.vbs
Sub Calculate()

    Dim lastRow As Long
    Dim firstRow As Long
    Dim index As Long
    Dim total As Double
    Dim average As Double
    Dim maxVal As Double
    Dim minVal As Double
    
    'A, B, C列のデータが入っている最終行を取得
    lastRow = Cells(Rows.Count, "A").End(xlUp).Row
    
    '2行目からデータを処理
    firstRow = 2
    
    '各行についてD列に合計値、E列に平均を計算し、最大値と最小値を色付け
    For index = firstRow To lastRow
    
        'A, B, C列の合計値を計算
        total = Cells(index, "A").Value + Cells(index, "B").Value + Cells(index, "C").Value
        Cells(index, "D").Value = total
        
        'A, B, C列の平均値を計算
        average = total / 3
        Cells(index, "E").Value = average
        
        '最大値を計算し赤色の太字に、最小値を計算し青色の太字にする
        maxVal = WorksheetFunction.Max(Range("A" & index & ":C" & index))
        minVal = WorksheetFunction.Min(Range("A" & index & ":C" & index))
        
        If Cells(index, "A").Value = maxVal Then
            Cells(index, "A").Font.Bold = True
            Cells(index, "A").Font.Color = vbRed
        End If
        
        If Cells(index, "B").Value = maxVal Then
            Cells(index, "B").Font.Bold = True
            Cells(index, "B").Font.Color = vbRed
        End If
        
        If Cells(index, "C").Value = maxVal Then
            Cells(index, "C").Font.Bold = True
            Cells(index, "C").Font.Color = vbRed
        End If
        
        If Cells(index, "A").Value = minVal Then
            Cells(index, "A").Font.Bold = True
            Cells(index, "A").Font.Color = vbBlue
        End If
        
        If Cells(index, "B").Value = minVal Then
            Cells(index, "B").Font.Bold = True
            Cells(index, "B").Font.Color = vbBlue
        End If
        
        If Cells(index, "C").Value = minVal Then
            Cells(index, "C").Font.Bold = True
            Cells(index, "C").Font.Color = vbBlue
        End If
        
    Next index

End Sub

'コメント文
'・各列の計算結果(合計、平均)はD列とE列に出力する
'・各行の最大値は赤色の太字、最小値は青色の太字にする
'・最大、最小値が複数ある場合、一番左の列を優先する
'・最大、最小値が同じ数字である場合、どの列でも太字、色付けされる。
'・値が0や負数の場合でも動作するようにする(最大・最小値が0や負数である場合も考慮)
'・入力されているデータ数が1000行以下である前提でよい

2回目はこのようになりました。

ex1_2.vbs
Sub Calculate()

    Dim lastRow As Long
    Dim firstRow As Long
    Dim index As Long
    Dim total As Double
    Dim average As Double
    Dim maxVal As Double
    Dim minVal As Double
    
    'A, B, C列のデータが入っている最終行を取得
    lastRow = Cells(Rows.Count, "A").End(xlUp).Row
    
    '2行目からデータを処理
    firstRow = 2
    
    '各行についてD列に合計値、E列に平均を計算し、最大値と最小値を色付け
    For index = firstRow To lastRow
    
        'A, B, C列の合計値を計算
        total = Cells(index, "A").Value + Cells(index, "B").Value + Cells(index, "C").Value
        Cells(index, "D").Value = total
        
        'A, B, C列の平均値を計算
        average = total / 3
        Cells(index, "E").Value = average
        
        '最大値を計算し赤色の太字に、最小値を計算し青色の太字にする
        
        '最大値を取得
        maxVal = WorksheetFunction.Max(Range("A" & index & ":C" & index))
        
        '最大値が出現した列を太字、赤色にする
        If Cells(index, "A").Value = maxVal Then
            Cells(index, "A").Font.Bold = True
            Cells(index, "A").Font.Color = vbRed
        ElseIf Cells(index, "B").Value = maxVal Then
            Cells(index, "B").Font.Bold = True
            Cells(index, "B").Font.Color = vbRed
        Else
            Cells(index, "C").Font.Bold = True
            Cells(index, "C").Font.Color = vbRed
        End If
        
        '最小値を取得
        minVal = WorksheetFunction.Min(Range("A" & index & ":C" & index))
        
        '最小値が出現した列を太字、青色にする
        If Cells(index, "A").Value = minVal Then
            Cells(index, "A").Font.Bold = True
            Cells(index, "A").Font.Color = vbBlue
        ElseIf Cells(index, "B").Value = minVal Then
            Cells(index, "B").Font.Bold = True
            Cells(index, "B").Font.Color = vbBlue
        Else
            Cells(index, "C").Font.Bold = True
            Cells(index, "C").Font.Color = vbBlue
        End If
        
    Next index

End Sub

'コメント文
'・各列の計算結果(合計、平均)はD列とE列に出力する
'・各行の最大値は赤色の太字、最小値は青色の太字にする
'・最大、最小値が複数ある場合、最初に出現する列を優先する(左から順に)
'・最大、最小値が同じ数字である場合、どの列でも太字、色付けされる。
'・値が0や負数の場合でも動作するようにする(最大・最小値が0や負数である場合も考慮)
'・入力されているデータ数が1000行以下である前提でよい```

そこまで変わりませんが、個人的には2回目の方が若干ですが読みやすくなっている気がしています。
 実行結果はどちらも想定通りの出力になっています。
実行結果1

実装例2

実装例2は以下のようなコードを出力しました。

ex2.vbs
Sub DrawGraph()
    'グラフを描画するための関数
    
    'グラフを描画するために必要な変数を宣言する
    Dim ws As Worksheet '描画するシート
    Dim chartObj As chartObject 'グラフを配置するオブジェクト
    Dim chart As chart 'グラフオブジェクト
    Dim dataRange As Range 'グラフを描画する範囲
    
    'グラフを描画するシートを指定する
    Set ws = ActiveWorkbook.Sheets("Sheet2")
    
    'グラフを配置するためのオブジェクトを追加する
    Set chartObj = ws.ChartObjects.Add(0, 0, 500, 300)
    
    'グラフオブジェクトを変数に代入する
    Set chart = chartObj.chart
    
    'グラフを描画する範囲を指定する
    Set dataRange = ws.Range("A2:B60") 
'例えばA列2~10行目とB列2~10行目までを描画する場合
   ‘というコメント文で Set dataRange = ws.Range("A2:B10")と記載されていた
    'グラフの種類を設定する
    chart.ChartType = xlLine
    
    'グラフの描画範囲を設定する
    chart.SetSourceData Source:=dataRange
    
    'グラフの軸の設定を行う
    chart.Axes(xlCategory).HasTitle = True
    chart.Axes(xlCategory).AxisTitle.Caption = "日付"
    
    chart.Axes(xlValue).HasTitle = True
    chart.Axes(xlValue).AxisTitle.Caption = "数量" ‘元は数値と記載されていた
    
    'グラフのタイトルを設定する
    chart.HasTitle = True
    chart.chartTitle.Text = "数量推移"’元はグラフタイトルと記載されていた
    
End Sub

サブルーチンの外には「※シート名や範囲は適宜変更して下さい」という文面もあり初心者でも修正しやすいコードだったと思っています。
結果は以下のようになります。
実行結果2

本記事のまとめと次回記事(予定)

本記事では、ChatGPTのAPIを用いたコーディングの実装方法を考えていきました。その結果、簡単なプログラムを実装できることが分かりました。次はもう少し複雑なプログラムでも実装可能であるかのケーススタディもしていきたいです。また、ChatGPTを用いたコーディング時間を削減する方法の節で述べた手順をブラッシュアップして、ChatGPTと他の自然言語処理モデルを組み合わせたノーコードプログラムの作成を考えていきたいです。

参考文献

Welcom to OpenAI
公式ドキュメント
ChatGPT APIキー取得までの手順
初心者向き OpenAI APIを使ってPythonでChatGPT遊びするための最初の三歩くらい
ChatGPTのAPIの利用料金を詳しく解説!使い方次第でトークン増大で高額費用も

Discussion