概述
- 随机自动为竞赛专业人士生成输入测试用例
- 介绍如何实现并看到面向对象的好处
不仅是那些想要使用自动生成功能的人,而且还有那些想知道比竞争专业人士更进一步的编程的人,
我认为学习面向对象编程的人可以阅读此内容。
完整的源代码可以在这里找到。
您可以做什么:自动生成输入测试用例
如果准备了这样的输入宏→
1 2 3 4 | Int(N,2,5) Float(a,1,100,5) Perm(1,N+4) Str([a-z]{3,2*N}) *N(2) |
输入将显示→
1 2 3 4 5 6 7 8 9 10 | output: 4 54.81887 3 2 4 7 1 8 5 6 yyl 4.32497 4 1 6 5 3 8 7 2 yziuqiac 42.84603 3 2 4 7 8 6 5 1 vsjajs 65.07176 7 5 8 3 4 6 1 2 rbq |
其他
加权图:
1 2 | Int(N,3,5) Int(M,N-1,N*(N-1)//2) Graph1(N,M,0,1000) |
↓
1 2 3 4 5 6 7 | output: 4 5 1 2 392 1 3 328 1 4 891 2 3 264 3 4 227 |
字符串:
1 2 3 | Int(N,4,6) Int(M,4,6) Str([.#]{M}) *N(1) |
↓
1 2 3 4 5 6 | output: 4 5 ###.# #.#.# #..## .###. |
等
如果您对
函数本身感兴趣,可以在此处找到列表。
*到目前为止,由于我们刚刚定义了内部类,因此,如果您想一次生成大量测试用例或将其写入文件,则需要使用此类对Python进行编码。
实现方法
它具有面向对象的实现。
大致上,
它分为
。这是我管理i 1并抛出必要工作(i = 1,2)的图像。
所有类都有以下共同的方法:
from_str():解析输入的宏字符串并初始化该类。
generate():为其管理的范围生成一个随机输入测试用例。
总之,它看起来像下表:
<表格>
tr>
header>
<身体>
tr>
tr>
tbody>
table>
重点是
- 要使用整体,LineCollection.from_str(输入宏)→generate()
- 如果要增加新的宏类型的数量,只需定义具有上述三种方法的Item类的子类即可(无需更改Line或LineCollection)。
是类似
的东西吗?
源代码
具体来说,我将检查源代码。
LineCollection
<表格>
tr>
header>
<身体>
tr>
tr>
tbody>
table>
self.ls具有宏的每一行的行列表。
支持" * N(1)"之类的宏有点复杂,但是我们要做的是
- from_str()=加载整个宏:初始化与每一行相对应的Line并将其放入self.ls
- generate()=为整个宏生成输出:为self.ls中的每一行生成输出,并以换行符返回
仅
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | class LineCollection: def __init__(self, ls, s=None): """ls: list of Line """ self.ls = ls self.s = s @classmethod def from_str(cls, s): lines = s.split("\n") i = 0 ls = [] for i in range(len(lines)): if lines[i].startswith("*"): name, num = lines[i][1:].split("(",1) num = int(num[:-1]) ls.append((name, num)) else: l = Line.from_str(lines[i]) ls.append(l) return cls(ls, s) def generate(self): i = 0 prv = 0 output = [] while i<len(self.ls): while i<len(self.ls) and not isinstance(self.ls[i], tuple): i += 1 if i<len(self.ls) and isinstance(self.ls[i], tuple): m, num = self.ls[i] i += 1 else: m = 0 num = 0 for j in range(prv, i-num-1): if isinstance(self.ls[j], tuple): continue output.append(self.ls[j].generate()) if num!=0: try: m = Item.names[m] except KeyError: raise ValueError("テストケース数が未定義: 上何行見るかの指定が間違っていません?") for _ in range(m): for j in range(i-num-1, i-1): if isinstance(self.ls[j], tuple): continue output.append(self.ls[j].generate()) prv = i return "\n".join(output) |
Line
<表格>
tr>
header>
<身体>
tr>
tr>
tbody>
table>
self.l管理您要查看的行中存在的项目列表。
类似于Line Collection,
- from_str():用空格分隔一行的读取,读取每个类的类名和参数,初始化Item,然后将其放到self.l中。
-
generate():让self.l中的每个Item生成输出并以空格返回结果