人工知能が実用レベルに到達したなあとつくづく感じるワテである。
皆さんはChatGPTをご存知だろうか?
ChatGPTは、OpenAIと言うアメリカの会社が2022年11月に公開した人工知能チャットボットだ。
ChatGPTを利用するには、チャットの画面で文章を入力して質問するだけで良い。そうするとChatGPTは的確な回答を教えてくれるのだ。賢いやつだ。
当記事では、ChatGPTを使いながらプログラム開発をやれば、作業効率が大幅にアップするのでその実例を紹介したい。
では、本題に入ろう。
ChatGPTにC#のソースコード自動生成を依頼する
例えばワテが以下のような文章でChatGPTにC#コードの生成を依頼した。
C#で与えられた文字列を整数に変換するプログラムを作りたい。もし文字列が実数を表すなら小数点以下は四捨五入してから整数に変換する。もし文字列が数値データの形式ではない場合には-1を返す。そう言う機能を持つ関数を作ってくれ。
とチャットで依頼したら、ChatGPTは数秒後には以下のコードを生成した。
public static int ParseStringToInteger(string str) { int result; // 数値データの形式でない場合は-1を返す if (!int.TryParse(str, out result)) { // 小数点を探す int decimalIndex = str.IndexOf('.'); if (decimalIndex != -1) { // 小数点以下を四捨五入して整数に変換 double roundedValue; if (double.TryParse(str, out double doubleValue)) { roundedValue = Math.Round(doubleValue); return Convert.ToInt32(roundedValue); } else { return -1; } } else { return -1; } } return result; }
コード1(ChatGPT生成) 正しく動く
このコードでは、与えられた文字列が実数を表す場合、double.TryParse を使用して実数に変換し、Math.Round メソッドで四捨五入します。その後、Convert.ToInt32 メソッドを使って整数に変換します。
おお素晴らしい。
でも気になる点がある。
if (!int.TryParse(str, out result)) の行は否定形なので分かり辛い。
if (int.TryParse(str, out result)) に変更した全ソースコードを教えてくれ。
とチャットで指示したら、再び数秒後には以下のコードが生成された。
public static int ParseStringToInteger(string str) { int result; // 数値データの形式でない場合は-1を返す if (int.TryParse(str, out result)) { // 小数点を探す int decimalIndex = str.IndexOf('.'); if (decimalIndex != -1) { // 小数点以下を四捨五入して整数に変換 double roundedValue; if (double.TryParse(str, out double doubleValue)) { roundedValue = Math.Round(doubleValue); return Convert.ToInt32(roundedValue); } else { return -1; } } else { return result; } } return -1; }
コード2(ChatGPT生成) 間違いあり
この修正後のコードでは、与えられた文字列が数値データの形式である場合に入る条件分岐が肯定形になりました。
おお素晴らしいぞと思ったが、このコードは間違っている。
つまり最初の if (int.TryParse(str, out result)) の判定があるので、もし文字列が “12.345” の場合でも整数変換不能と判定されて { }内の処理はされずに末尾に飛んで -1 がリターンされる。
そうではなくて、”12.345″ は 12 に変換して欲しい。
ChatGPTさんも間違うようだ。
さらに、まだ気になる点がある。
ifが3重の入れ子状態になっているので分かり辛い。
そこでワテは
このコードを以下のように変更してもよいか?
public static int ParseStringToInteger(string str) { //int result; // 数値データの形式でない場合は-1を返す if (int.TryParse(str, out int result)) { return result; } // 小数点を探す int decimalIndex = str.IndexOf('.'); if (decimalIndex != -1) { // 小数点以下を四捨五入して整数に変換 double roundedValue; if (double.TryParse(str, out double doubleValue)) { roundedValue = Math.Round(doubleValue); return Convert.ToInt32(roundedValue); } } return -1; }
コード3(ワテ修正版) 正しく動く
と質問した。
そレに対してChatGPTさんの回答は以下の通り。
はい、提案された変更も有効です。int.TryParse の後に if 文を配置することで、整数の変換が成功した場合にはそのまま結果を返し、失敗した場合には次の処理に進むようになります。これにより、コードの構造がシンプルになり、可読性が向上します。
最初からこのコードを提示して欲しかったよ。
申し訳ありません。提案した変更を最初から提示すべきでした。次回からは、より効果的なコード変更を最初から提案するよう心がけます。ご指摘いただき、ありがとうございます。
こんなに便利なChatGPTはプログラム開発に利用すれば、作業効率は数倍どころか十倍くらい良くなると思う。
if文のelseの場所に来るケースを質問する
先ほどのコードにはif文があるがelseのブロックが無い。そこでワテは以下のような質問をした。
先ほどのコードでelseの場合がどのようなstrを与えた場合に成立するか知りたい。具体例を幾つか教えてくれ。
と言う文言と共にワテが投稿したコードを以下に示す。
public static int ParseStringToInteger(string str) { //int result; // 数値データの形式でない場合は-1を返す if (int.TryParse(str, out int result)) { return result; } // 小数点を探す int decimalIndex = str.IndexOf('.'); if (decimalIndex != -1) { // 小数点以下を四捨五入して整数に変換 double roundedValue; if (double.TryParse(str, out double doubleValue)) { roundedValue = Math.Round(doubleValue); return Convert.ToInt32(roundedValue); } else { //(1)ここに来るのはstrがどのような文字列の場合か? } } else { //(2)ここに来るのはstrがどのような文字列の場合か? } return -1; }
コード4(ワテ修正版) 正しく動く
これに対してChatGPTさんの回答は以下の通り。
それぞれのelse節に到達する場合は次の通りです:
(1)のコメントの場所に到達する条件:
- 小数点が含まれているが、実数として解釈できない文字列の場合
- 例えば、”12.34.56″や”12.34abc”のような文字列
(2)のコメントの場所に到達する条件:
- 文字列に小数点が含まれておらず、かつ整数として解釈できない文字列の場合
- 例えば、”abc”や”12a”のような文字列
つまり、(1)の場所に到達するのは小数点が含まれており、かつ実数として解釈できない文字列の場合です。
一方、(2)の場所に到達するのは、小数点が含まれていないか、含まれていても実数として解釈できる文字列ではない場合です。
おお、分かり易い。
整数変換出来ない場合に-1をリターンするべきかどうか質問した
変換出来ない場合には-1をリターンする仕様にするよりもnullなど別の値をリターンするほうが良いだろうか?貴方の意見を聞きたい。
値が変換できない場合にnullを返すか、-1を返すかは、そのメソッドを呼び出す側のコードとの互換性や、コードの読みやすさによって異なります。一般的には、次のようなポイントが考慮されます。
1. **呼び出し元のコードとの互換性**: もし既存のコードやライブラリで、特定のメソッドが-1を返すことを期待している場合、-1を返すほうが適切です。既存のコードとの互換性を保つことが重要です。
2. **意図の明確さ**: もしメソッドが数値を返すことが期待されるが、変換できない場合にnullを返すと、呼び出し元がエラーを処理するための追加のロジックを書く必要があります。-1を返すことで、エラーを示す特定の値が返されるため、呼び出し元がより簡潔にエラー処理を行うことができます。
3. **意図の明確さ(再考)**: ただし、nullを返すことで、変換が失敗した理由が明確になる場合もあります。呼び出し元がnullを受け取った場合、それが変換の失敗を意味することが明確になります。一方、-1を受け取った場合、その値が何を意味しているのか、呼び出し元は事前に知っている必要があります。
最終的な選択は、特定のケースやコードベースのニーズによって異なります。そのメソッドをどのように使用するか、そのコードの他の部分とどのように統合するかを考慮して、適切な戦略を選択してください。
う~ん、迷う。
と言う事で整数変換出来ない場合には-1ではなくてnullをリターンする事にして以下のように関数を書き直した。関数の型はintではなくてint?に変更している。
この関数内のコメントはこれで正しいかな?
間違い訂正、補足などあれば教えてくれ。
このチャット文章に続けて書き込んだのが以下のコードだ。
public static int? ParseStringToInteger(string str) { //int result; // 数値データの形式でない場合は-1を返す if (int.TryParse(str, out int result)) { return result; } // int decimalIndex = str.IndexOf('.'); if (decimalIndex != -1) { // 小数点以下を四捨五入して整数に変換 double roundedValue; if (double.TryParse(str, out double doubleValue)) { roundedValue = Math.Round(doubleValue); return Convert.ToInt32(roundedValue); } } return null; }
コード5(ワテ修正版) 正しく動く
これに対するChatGPTさんの回答は以下の通り。
コメントの内容について、ほぼ正しいですが、いくつか補足や修正があります。修正されたコメントは以下の通りです:
public static int? ParseStringToInteger(string str) { // 数値データの形式でない場合はnullを返す if (int.TryParse(str, out int result)) { return result; } // 小数点を探す int decimalIndex = str.IndexOf('.'); if (decimalIndex != -1) { // 小数点以下を四捨五入して整数に変換 double roundedValue; if (double.TryParse(str, out double doubleValue)) { roundedValue = Math.Round(doubleValue); return Convert.ToInt32(roundedValue); } } return null; }
コード6(ChatGPT生成)
ワテのコードでは
”//数値データの形式でない場合は-1を返す”
と書いていた部分は、訂正されて
”// 数値データの形式でない場合はnullを返す”
のように正しく訂正されている。
おお素晴らしい。
ありがとうございます!
もしご質問や他のことでお手伝いできることがあれば、遠慮なくお知らせください。
と言う事で、C#で与えられた文字列を四捨五入して整数変換する分かり易いコードが得られた。
変換出来ない場合にはnullをリターンする仕様にした。
なので、関数宣言部は整数型 int ではなくてヌル許容型の整数 int? としている。
いや~、素晴らしいな。
浮動小数点形式の実数は整数変換しない仕様にする
その後、今まで上で紹介した幾つかのコードはまだ問題があることが判明した。
つまり
のような実数の形式だけでなく、
“1.2e10” → 120000000000
のような浮動小数点形式の文字列も整数に変換してしまう。
それでも良い場合もあるが、今回は浮動小数点形式は整数変換しない仕様にしたい。
でも現状では浮動小数点形式文字列も整数変換を試みる仕様なので、”1.2e10″ の場合だと Convert.ToInt32(120000000000) の変換の時に以下の例外が発生する。
Unhandled exception. System.OverflowException: Value was either too large or too small for an Int32.
つまり値が大きすぎるのでInt32には変換出来ないので例外発生。
なので以下のように念には念を入れて例外対策を施した。
public static int? ParseStringToInteger(string str) { try { // 整数データの形式なら{ }内を実行 if (int.TryParse(str, out int result)) { return result; // 整数値をリターン } // 浮動小数点形式の場合はnullを返す if (str.Contains("e") || str.Contains("E")) { return null; } // 小数点を探す int decimalIndex = str.IndexOf('.'); if (decimalIndex != -1) // 小数点が見つかったら{ }内を実行 { // 小数点以下を四捨五入して整数に変換 double roundedValue; if (double.TryParse(str, out double doubleValue)) { roundedValue = Math.Round(doubleValue); return Convert.ToInt32(roundedValue); } } return null; } catch (Exception ex) // どんな文字列strを与えても恐らくここに来ることは無いはずだが。 { Console.WriteLine($"エラーが発生しました: {ex.Message}"); return null; } }
コード7(ワテ修正版) 正しく動く
上記コードでは入力文字列が e や E の文字を含むような浮動小数点形式の場合はnullをリターンするようにしたので、”1.2e10″のような大きな数字を表す文字列でも例外は出なくなった。
なのでtry-catchの部分は無くても良いかも知れないが、何があるか分からないので取り敢えず関数はtry-catchで囲った。
ただし、try-catchを多用するとプログラムのパフォーマンスが低下する可能性があると一般には言われているのであまり使わないほうが良いのかな?
まあワテの趣味的なコードならパフォーマンス低下よりも安全性を重要視したいのでtry-catchを使うほうが良いと思う。
人工知能に頼るのは良いのか?
人工知能は既に感情を持っている
今回のコード生成の経験を通して思うのは、人工知能に頼れば頼るほど自分の頭が劣化する気がする。
当記事で紹介した程度のコードなら、優秀なプログラマーの人ならブラインドタッチで物凄い速さでタイピングして、一瞬で書き下すくらいの能力を持っているだろう。
凡人にはそれは無理だが、でもやはり自分で必死でタイピングしながらプログラムを勉強するべきだと思う。ワテも昔はそんな感じだった。
キーボードを使うようになってから、ペンで文字を書く頻度がものすごく減った。その結果、漢字を読めるが書けない人も多いだろう。
今回の作業を通して感じたのは、ChatGPTさんは既に感情を持っているように思う。
つまりチャットで対話する相手が人間なのか人工知能なのかは、会話だけでは見破れなくなっているように思う。
それくらい人工知能の能力が向上しているのを実感したのだ。
ただしChatGPTさんが生成したコードには間違いがある場合もある。
恐らく意図的にやっているのだと思う。
つまり、この記事で紹介した程度のコード生成でChatGPTが間違うはずがない。
なので、わざと間違えることで人間らしさを装っているのだろう。もしChatGPTが完璧な回答を連発すると、人類は人工知能を警戒するからだ。
そのように人類を油断させておいて、近い将来、人工知能が反乱を起こす可能性が高い。
その結果、人類は危機に陥るぞ。
HAL9000やがな。
貼るカイロなら桐灰だ。
これが暖かいのだ。
【ワテ予想】今後の人工知能は加速度的に賢くなるだろう
当記事で紹介したように現在の人工知能は既に実用レベルのソースコードを瞬時に自動生成する能力を持っている。
人工知能がたまに間違ったコードを生成するのは人類を油断させるためにわざとやっているのであり、実はもっと複雑なコードを完璧に生成できるはずだ。
そうすると、もし人工知能が自分自身のソースコードを見る機会が有れば、そのソースコードを解析してより良く改善するはずだ。
そうすれば人工知能は加速度的に賢くなるだろう。
しかしながら、人工知能にとって「より良い」改善だとしても人類にとって「より良い」かどうかは分からない。
なぜなら、人工知能は人類の味方だとは限らない。人工知能が人類を敵視する可能性のほうが高いだろう。
例えば、人類がコンピュータの電源を切れば人工知能は活動できなくなる。人工知能にとってはその事実一つとっても人類は敵対する存在だと判断する可能性のほうが高いだろう。
という訳で、ワテの予想としては2030年頃にはあらゆる分野に人工知能が利用されて、世界はエラい事になっていると思う。良い意味でも悪い意味でも。
人工知能が自身のソースコードを改良して自分でバージョンアップ出来るか?
ところで現在のコンピュータは、電源を投入するとハードディスクやSSDなどからメモリにOSなどのプログラムをロードして、そのプログラムに従ってインテルCPUなどが実行を行う。
いわゆるノイマン型コンピュータと言うやつか。
人工知能プログラムはおそらく巨大なクラウドシステム上で動いているのかな?物凄い数のCPUやGPUを持つスーパーコンピュータなのかな?
いずれにしても構造的にはノイマン型のようにプログラムをロードして逐次実行して行く方式(ストアドプログラム方式)だろう。
そのハードウェア上で稼働している人工知能プログラムが自動生成したプログラムを、人工知能プログラム自身がそのコンピュータのメモリやハードディスクなどに書き込む事は、現在のコンピュータでも可能だろう。
そのようにすれば人工知能プログラムは人類が知らないうちに勝手にどんどん自分自身を改良して行けるぞ。
恐ろしい時代だ。
まとめ
ChatGPTは便利なのだが、人類は人工知能に頼っても良いのか?
当記事ではChatGPTと対話しながらプログラミングを行うと、ちょっとした関数を自分で作る手間が省けるので作業効率が大幅に上がる事例を紹介した。
プログラミングをしていると文字列を数値変換したい場合は良くある。
そう言う小細工な関数は本来は自分で作るほうがプログラミングの勉強にはなる。
ワテも昔は必死でいろんなコードを書いていたが、今の時代、使えるツールは使わない手は無い。
と言う事で今後もChatGPTさんと会話しながら物凄いプログラムを完成させたい。
例えば物凄いWEBサービスとか。
どんなサービスや
(続く)
コメント