code-generationの利用
Pythonパッケージcode-generationについて解説しています。前記事は以下です。
前回の記事では具体的な用途を書けていませんでした。
このツールの利点は、あるルールに従ってコードを多数生成できることだと思います。例えば、以下のケースでは役立つことがありそうです。
- テストコード作成
- 実行時のコード生成
- ランダムなコード生成
テストコード生成
実装が一部異なる関数は簡単に作成できるため、テストケースを水増しできます。
from code_generation import code_generator
from code_generation.cpp_function import CppFunction
cpp = code_generator.CppFile("example.cpp")
# テスト対象に与える引数、戻り値の解
factorial_arguments, factorial_answers = \
["-5", "-1", "2", "3", "8"], ["1", "1", "2", "6", "40320"]
for arg, ans in zip(factorial_arguments, factorial_answers):
def testBody(self, cpp):
cpp("EXPECT_EQ(" + ans + ", Factorial(" + arg + "));")
factorial_function = CppFunction(name="Test",
ret_type="",
implementation_handle=testBody)
factorial_function.add_argument("IntegerFunctionTest, Factorial")
factorial_function.render_to_string(cpp)
cpp.newline()
↓
Test(IntegerFunctionTest, Factorial)
{
EXPECT_EQ(1, Factorial(-5));
}
Test(IntegerFunctionTest, Factorial)
{
EXPECT_EQ(1, Factorial(-1));
}
Test(IntegerFunctionTest, Factorial)
{
EXPECT_EQ(2, Factorial(2));
}
Test(IntegerFunctionTest, Factorial)
{
EXPECT_EQ(6, Factorial(3));
}
Test(IntegerFunctionTest, Factorial)
{
EXPECT_EQ(40320, Factorial(8));
}
実行時のコード生成
用途は特に限られると思いますが、実行時にコードが作られるのを利点と考えることもできます。
from code_generation import code_generator
import datetime
cpp = code_generator.CppFile("example.cpp")
JST = datetime.timezone(datetime.timedelta(hours=9), "JST")
now = datetime.datetime.now(JST)
cpp("// Generated at " + now.strftime('%Y/%m/%d %H:%M:%S'))
↓
// Generated at 2024/06/29 00:01:00
ランダムなコード生成
規則的またはランダムなコードを作りたい時には、簡単に作成できます。
from code_generation import code_generator
from code_generation.cpp_function import CppFunction
import random
# 10個ファイルを作成
for i in range(10):
cpp = code_generator.CppFile("code_"+str(i)+".cpp")
def funcBody(self, cpp):
cpp("double tmp = 0;")
with cpp.block("for(int i=0; i<n; ++i)", ""):
for _loop in range(random.choice(range(1,5))):
# この処理は1~5回繰り返す、演算は"*/+-"からランダムに選ぶ
cpp("tmp += a[i] " + random.choice("*/+-") + " b[i];")
cpp("c[i] = tmp;")
factorial_function = CppFunction(name="f",
ret_type="void",
implementation_handle=funcBody)
factorial_function.add_argument("const double* a, const double* b, double* c, int n")
factorial_function.render_to_string(cpp)
↓(以下のようなコードが10個生成される)
void f(const double* a, const double* b, double* c, int n)
{
double tmp = 0;
for(int i=0; i<n; ++i)
{
tmp += a[i] - b[i];
tmp += a[i] * b[i];
tmp += a[i] + b[i];
tmp += a[i] - b[i];
c[i] = tmp;
}
}