如何构建策略来创建具有相同值对的元组数组?
How to build a strategy to create array of tuples with pairs of identical values?
我想为 NumPy 测试生成一个策略,输出如下:
array([[-2, -2],
[-3, -3],
[5, 5],
[-1, -1]], dtype=int16)
我试过的是:
import numpy as np
from hypothesis.strategies import integers
from hypothesis.extra.numpy import arrays
arrays(np.int16, (4,2), elements=integers(-10, 10)).example()
不幸的是,我无法使元组内的值相同,所以上面的查询 returns:
array([[ 5, 5],
[-7, 5],
[ 5, 5],
[ 5, 5]], dtype=int16)
无需过多研究 np 必须提供的内容,您可以使用生成器生成元组:
tuple_list = [tuple(a) for a in arrays(np.int16, (4,2), elements=integers(-10,10)).example()]
不确定这就是您想要的,但是 hypothesis.extra.numpy
中的 arrays
似乎没有重复值的选项。
你可以像这样构建你需要的数组:
import numpy as np
from hypothesis.strategies import integers
strat = integers(10, -10)
np.array([[x, x] for x in [strat.example() for _ in range(4)]], np.int16)
示例结果:
array([[-9, -9],
[ 0, 0],
[-2, -2],
[ 0, 0]], dtype=int16)
如果您不喜欢内置 2
维度,您可以像这样设置两个参数:
def get_array(rows, cols, strat):
np.array([[x]*cols for x in [strat.example() for _ in range(rows)]], np.int16)
get_array(4, 2, integers(-10, 10))
我发现,如果我需要在 内 现有策略的结构中控制内容(例如, 在 数组内的相同值对)对于较低级别的策略,我需要跳过该策略,我可以使用它来构建一个 "ready-made" 值,该值可以为我想要生成的类型提供种子。
让我们利用 numpy.array 接受列表的列表来创建数组。我们还假设您希望每一行都是唯一的,因为您的示例没有显示重复的行。如果不需要,请从 depth_strategy
定义
中删除 unique_by=str
- 生成一个整数并创建一个重复多次以满足宽度的值的列表。
- 生成我们在第一步中创建的那种列表的深度长度列表。
- 通过嵌套将两种策略结合起来。
- 将第三步的结果输入 numpy.array,确保 dtype 与第一步中用于生成值的策略相匹配。
# %%
"""Hypothesis strategy for array of tuples with pairs of identical values."""
from hypothesis import given, settings, strategies as st
import numpy as np
WIDTH = 2
DEPTH = 4
MIN_VALUE = -10
MAX_VALUE = 10
# Build the row - Here for clarification only
width_strategy = st.integers(MIN_VALUE, MAX_VALUE).map(
lambda i: tuple(i for _ in range(WIDTH))
)
# Build the array of rows - Here for clarification only
depth_strategy = st.lists(
width_strategy, min_size=DEPTH, max_size=DEPTH, unique_by=str
).map(lambda lot: np.array(lot, dtype=np.int64))
# All-in-One
complete_strategy = st.lists(
st.integers(MIN_VALUE, MAX_VALUE).map(
lambda i: tuple(i for _ in range(WIDTH))
),
min_size=DEPTH,
max_size=DEPTH,
unique_by=str,
).map(lambda lot: np.array(lot, dtype=np.int64))
@settings(max_examples=10)
@given(an_array=complete_strategy)
def create_numpy_array(an_array):
"""Turn list of lists into numpy array."""
print(f"A numpy array could be:\n{an_array}")
create_numpy_array()
这会生成如下内容:
A numpy array could be:
[[ 3 3]
[ 9 9]
[-5 -5]
[ 0 0]]
A numpy array could be:
[[ 3 3]
[-2 -2]
[ 4 4]
[-5 -5]]
A numpy array could be:
[[ 7 7]
[ 0 0]
[-2 -2]
[-1 -1]]
请注意,我将 max_examples 设置为 10,因为假设给出了它认为 "troublesome" 的值更高的出现率,例如零、NaN、无穷大等。因此 example() 或更少数量的示例可能会生成大量全为零的 2x4 数组。幸运的是,unique_by 约束在这里帮助了我们。
我想为 NumPy 测试生成一个策略,输出如下:
array([[-2, -2],
[-3, -3],
[5, 5],
[-1, -1]], dtype=int16)
我试过的是:
import numpy as np
from hypothesis.strategies import integers
from hypothesis.extra.numpy import arrays
arrays(np.int16, (4,2), elements=integers(-10, 10)).example()
不幸的是,我无法使元组内的值相同,所以上面的查询 returns:
array([[ 5, 5],
[-7, 5],
[ 5, 5],
[ 5, 5]], dtype=int16)
无需过多研究 np 必须提供的内容,您可以使用生成器生成元组:
tuple_list = [tuple(a) for a in arrays(np.int16, (4,2), elements=integers(-10,10)).example()]
不确定这就是您想要的,但是 hypothesis.extra.numpy
中的 arrays
似乎没有重复值的选项。
你可以像这样构建你需要的数组:
import numpy as np
from hypothesis.strategies import integers
strat = integers(10, -10)
np.array([[x, x] for x in [strat.example() for _ in range(4)]], np.int16)
示例结果:
array([[-9, -9],
[ 0, 0],
[-2, -2],
[ 0, 0]], dtype=int16)
如果您不喜欢内置 2
维度,您可以像这样设置两个参数:
def get_array(rows, cols, strat):
np.array([[x]*cols for x in [strat.example() for _ in range(rows)]], np.int16)
get_array(4, 2, integers(-10, 10))
我发现,如果我需要在 内 现有策略的结构中控制内容(例如, 在 数组内的相同值对)对于较低级别的策略,我需要跳过该策略,我可以使用它来构建一个 "ready-made" 值,该值可以为我想要生成的类型提供种子。
让我们利用 numpy.array 接受列表的列表来创建数组。我们还假设您希望每一行都是唯一的,因为您的示例没有显示重复的行。如果不需要,请从 depth_strategy
定义
unique_by=str
- 生成一个整数并创建一个重复多次以满足宽度的值的列表。
- 生成我们在第一步中创建的那种列表的深度长度列表。
- 通过嵌套将两种策略结合起来。
- 将第三步的结果输入 numpy.array,确保 dtype 与第一步中用于生成值的策略相匹配。
# %%
"""Hypothesis strategy for array of tuples with pairs of identical values."""
from hypothesis import given, settings, strategies as st
import numpy as np
WIDTH = 2
DEPTH = 4
MIN_VALUE = -10
MAX_VALUE = 10
# Build the row - Here for clarification only
width_strategy = st.integers(MIN_VALUE, MAX_VALUE).map(
lambda i: tuple(i for _ in range(WIDTH))
)
# Build the array of rows - Here for clarification only
depth_strategy = st.lists(
width_strategy, min_size=DEPTH, max_size=DEPTH, unique_by=str
).map(lambda lot: np.array(lot, dtype=np.int64))
# All-in-One
complete_strategy = st.lists(
st.integers(MIN_VALUE, MAX_VALUE).map(
lambda i: tuple(i for _ in range(WIDTH))
),
min_size=DEPTH,
max_size=DEPTH,
unique_by=str,
).map(lambda lot: np.array(lot, dtype=np.int64))
@settings(max_examples=10)
@given(an_array=complete_strategy)
def create_numpy_array(an_array):
"""Turn list of lists into numpy array."""
print(f"A numpy array could be:\n{an_array}")
create_numpy_array()
这会生成如下内容:
A numpy array could be:
[[ 3 3]
[ 9 9]
[-5 -5]
[ 0 0]]
A numpy array could be:
[[ 3 3]
[-2 -2]
[ 4 4]
[-5 -5]]
A numpy array could be:
[[ 7 7]
[ 0 0]
[-2 -2]
[-1 -1]]
请注意,我将 max_examples 设置为 10,因为假设给出了它认为 "troublesome" 的值更高的出现率,例如零、NaN、无穷大等。因此 example() 或更少数量的示例可能会生成大量全为零的 2x4 数组。幸运的是,unique_by 约束在这里帮助了我们。