Taste of Tech Topics

Acroquest Technology株式会社のエンジニアが書く技術ブログ

Amazon Bedrock(Claude2)でPythonのソースコード/テストコードの生成を確認してみた

こんにちは、最近久々にソロキャンプをしてきました菅野です。

AWS上で、 様々なAIモデルを利用できるようになるサービス、Amazon Bedrockがリリースされました、と書き続けてそろそろひと月が経過しております。
楽しみながら様々なモデルを利用していたらあっという間に時間がたってしまいました。

今回は、BedrockのClaudeV2モデルを用いてPythonコードとテストコードを生成してみようと思います。

Bedrockの説明は、以下を参照してください。

acro-engineer.hatenablog.com

Fizz Buzz」の生成

プログラミングの初歩も初歩、定番の課題といえばFizz Buzzです。
1-100までの数字のうち、3の倍数の時にはFizzを、5の倍数の時はBuzzを、3の倍数且つ、5の倍数の時はFizzBuzzと、それ以外の時はその数字を表示するプログラムです。

早速コードを生成してもらいましょう。

以下のようなコードが出力されました。

"""FizzBuzz問題を解くモジュール。

このモジュールにはFizzBuzz問題を解くためのクラスと関数が含まれます。
"""

class FizzBuzz:
    """FizzBuzz問題を解くためのクラス。

    このクラスにはFizzBuzzのルールに基づいて文字列を生成するメソッドが含まれます。
    """

    def generate(self, n: int) -> str:
        """nを受け取りFizzBuzzのルールに基づいた文字列を返す。

        Args:
            n (int): FizzBuzzを行う数値

        Returns:
            str: FizzBuzzのルールに基づいた文字列
        """
        
        if n % 15 == 0:
            return "FizzBuzz"
        elif n % 3 == 0:
            return "Fizz"
        elif n % 5 == 0:
            return "Buzz"
        else:
            return str(n)


def main():
    """メインメソッド。FizzBuzzクラスの使用例を示す。"""
    
    fizzbuzz = FizzBuzz()
    
    for i in range(1, 21):
        print(fizzbuzz.generate(i))


if __name__ == "__main__":
    main()

出力されたコードのテストコードも作成してもらいましょう。 以下のコードが出力されました。

import pytest
from fizzbuzz import FizzBuzz

@pytest.mark.parametrize(
    "n, expected",
    [
        (1, "1"),
        (2, "2"), 
        (3, "Fizz"),
        (4, "4"),
        (5, "Buzz"),
        (6, "Fizz"),
        (10, "Buzz"),
        (15, "FizzBuzz"),
    ]
)
def test_fizzbuzz(n, expected):
    fizzbuzz = FizzBuzz()
    assert fizzbuzz.generate(n) == expected

一回でFizzBuzzを実行するコード、ユニットテストを生成することができました。
Fizz、Buzz、FizzBuzz、自身の数それぞれのパターンをテストで確認できています。

じゃんけんを実行するコード

もう少し、複雑なコードも作成してもらいましょう。
ユーザの入力をもとにじゃんけんを実施するコードを作ってもらいましょう。 (中略)

以下のコードが生成されました。

"""じゃんけんゲームを実行するモジュール。"""

from random import randint

class JankenGame:
    """じゃんけんゲームを表すクラス。

    属性:
      player_hand: プレイヤーの選択した手
      computer_hand: コンピュータの選択した手
    """

    def __init__(self):
        """コンストラクタ"""
        self.player_hand = None
        self.computer_hand = None

    def get_computer_hand(self):
        """コンピュータの手をランダムに選択する。

        返り値:
          コンピュータの選択した手(グー、チョキ、パーのいずれか)
        """
        hands = ["グー", "チョキ", "パー"]
        return hands[randint(0, 2)]

    def judge(self):
        """勝敗を判定する。

        返り値: 
          "player": プレイヤーの勝ち
          "computer": コンピュータの勝ち 
          "draw": 引き分け
        """

        # 判定ロジック
        if self.player_hand == "グー":
            if self.computer_hand == "チョキ":
                return "player"
            elif self.computer_hand == "パー":
                return "computer"
        elif self.player_hand == "チョキ":
            if self.computer_hand == "パー":
                return "player"
            elif self.computer_hand == "グー":
                return "computer"
        elif self.player_hand == "パー":
            if self.computer_hand == "グー":
                return "player"
            elif self.computer_hand == "チョキ":
                return "computer"

        return "draw"

def main():
    """メイン処理。"""
    game = JankenGame()

    # プレイヤーの手を入力
    player_hand = input("あなたの手を入力してください(グー、チョキ、パー): ")
    game.player_hand = player_hand

    # コンピュータの手を決定
    computer_hand = game.get_computer_hand()
    print(f"コンピュータの手: {computer_hand}")
    game.computer_hand = computer_hand

    # 勝敗を判定
    result = game.judge()
    print(f"結果: {result}")

if __name__ == "__main__":
    main()

一回で期待通りのコードが出力されました。

同様に、上記コードのテストを実装してもらいましょう。

以下のようなテストコードが出力されました。

import pytest
from janken import JankenGame

@pytest.mark.parametrize("player, computer, expected", [
    ("グー", "チョキ", "player"),
    ("グー", "パー", "computer"), 
    ("チョキ", "パー", "player"),
    ("チョキ", "グー", "computer"),
    ("パー", "グー", "player"),
    ("パー", "チョキ", "computer"),
    ("グー", "グー", "draw"), 
    ("チョキ", "チョキ", "draw"),
    ("パー", "パー", "draw")
])
def test_judge(player, computer, expected):
    game = JankenGame()
    game.player_hand = player
    game.computer_hand = computer
    assert game.judge() == expected

じゃんけん結果判定のそれぞれのパターンについてテストができていますね。

まとめ

Claude 2でPythonコードと、pytestのテストコードを生成してもらいました。 簡単なAssertionのみの出力となりましたが一回でテストを生成できたのはうれしいポイントでした。
ソースコードも一回の出力でエラーなく期待する挙動のコードが出てきたのも高ポイントですね。 コツとして、プロダクトコードの作成時に「関数は適宜戻り値を返すようにしテスト作成しやすいようにする」と指示すると、関数をテストしやすく作ってくれる確率が高まります。 今後も生成AIでできることを模索していきたいです。
それでは。

Acroquest Technologyでは、キャリア採用を行っています。
  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSクラウドサービスを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長
  少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。 www.wantedly.com