Skip to content

Commit 78c20db

Browse files
fix: refactored tests in medidas
1 parent 5299be0 commit 78c20db

9 files changed

Lines changed: 376 additions & 333 deletions

pyproject.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,12 @@ linter = [
5353
"ruff>=0.15.21",
5454
]
5555
test = [
56-
"labifsc >=0.1.13,<0.2.0",
57-
"uncertainties >=3.2.2,<4.0.0",
5856
"pytest >=9.1.1,<10.0.0",
5957
"pytest-cov >=7.1.0,<8.0.0",
6058
"scipy >=1.15.1,<2.0.0",
6159
"mutmut >=3.6.0,<4.0.0",
6260
"matplotlib >=3.10.0,<4.0.0",
61+
"mcerp>=1.1.0",
6362
]
6463

6564
[tool.mypy]

tests/medida/conftest.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from collections.abc import Iterator
22

3+
import mcerp
34
import numpy as np
45
import pytest
56
from numpy.typing import NDArray
@@ -8,6 +9,19 @@
89
from tests.utilities import SEMENTE_MONTE_CARLO
910

1011

12+
@pytest.fixture(autouse=True)
13+
def configurar_rng_mcerp() -> Iterator[None]:
14+
estado = np.random.get_state()
15+
quantidade_amostras = mcerp.npts
16+
np.random.seed(SEMENTE_MONTE_CARLO % 2**32)
17+
mcerp.npts = 100_000
18+
try:
19+
yield
20+
finally:
21+
np.random.set_state(estado)
22+
mcerp.npts = quantidade_amostras
23+
24+
1125
@pytest.fixture
1226
def rng_testes() -> np.random.Generator:
1327
return np.random.Generator(np.random.PCG64(SEMENTE_MONTE_CARLO))

tests/medida/test_classe_medida.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ def test_inicializacao_escalar_e_conversao_si(medida: lab.Medida) -> None:
4949
def test_inicializacao_por_amostras_usa_media_e_desvio_amostral() -> None:
5050
medida = lab.Medida([1, 2, 3], "s")
5151
assert medida.nominal("s") == pytest.approx(2)
52-
assert medida.incerteza("s") == pytest.approx(np.std([1,2,3], ddof=1))
53-
assert medida.incerteza("s") != pytest.approx(np.std([1,2,3])) #without ddof=1
52+
assert medida.incerteza("s") == pytest.approx(np.std([1, 2, 3], ddof=1))
53+
assert medida.incerteza("s") != pytest.approx(np.std([1, 2, 3])) # without ddof=1
5454

5555

5656
def test_inicializacao_por_amostras_preserva_maior_incerteza() -> None:

tests/medida/test_classe_medida_operacoes.py

100755100644
Lines changed: 103 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -1,131 +1,114 @@
1+
from collections.abc import Callable
2+
13
import numpy as np
24
import pytest
5+
from numpy.typing import NDArray
6+
from pint import Quantity
37

48
import LabIFSC2 as lab
59
from tests.utilities import assert_medida_proxima
610

711

8-
def test_soma():
9-
10-
x, y = lab.Medida(0, "", 0.1), lab.Medida(5, "", 0.3)
11-
12-
assert (y + 3).nominal("") == 8
13-
assert (y - 3).nominal("") == 2
14-
assert (y - 3.13).nominal("") == 5 - 3.13
15-
16-
incerteza_esperada = np.hypot(0.1, 0.3)
17-
assert_medida_proxima(x + y, 5, incerteza_esperada)
18-
assert_medida_proxima(y + x, 5, incerteza_esperada)
19-
assert_medida_proxima(x - y, -5, incerteza_esperada)
20-
assert_medida_proxima(y - x, 5, incerteza_esperada)
21-
22-
assert_medida_proxima(x - x, 0, 0)
23-
assert_medida_proxima(y - y, 0, 0)
24-
z = lab.Medida(5, "", 0.01) * lab.Medida(5, "", 0.01)
25-
w = lab.Medida(5, "", 0.01)
26-
assert np.isclose((z + w).nominal(""), 30, 1e-4)
27-
assert np.isclose((z - w).nominal(""), 20, 1e-4)
28-
29-
30-
def test_multiplicacao_medidas():
31-
x = lab.Medida(0, "", 0.1)
32-
y = lab.Medida(0, "", 0.1)
33-
correlacionado = x * x
34-
nao_correlacionado = lab._medida.montecarlo(lambda a, b: a * b, x, y)
35-
assert not (np.any(correlacionado.histograma) < 0)
36-
assert np.any(nao_correlacionado.histograma > 0) and np.any(
37-
nao_correlacionado.histograma < 0
38-
)
39-
assert not (
40-
correlacionado._histograma is None and nao_correlacionado._histograma is None
12+
def test_operacoes_com_a_mesma_medida_preservam_correlacao() -> None:
13+
medida = lab.Medida(5, "", 0.1)
14+
medida_clone = lab.Medida(5, "", 0.1)
15+
assert_medida_proxima(medida + medida, 10, 0.2)
16+
assert_medida_proxima(medida - medida, 0, 0)
17+
assert_medida_proxima(medida / medida, 1, 0)
18+
with pytest.raises(AssertionError):
19+
assert_medida_proxima(medida + medida_clone, 10, 0.2)
20+
with pytest.raises(AssertionError):
21+
assert_medida_proxima(medida - medida_clone, 0, 0.0)
22+
with pytest.raises(AssertionError):
23+
assert_medida_proxima(medida / medida_clone, 1, 0)
24+
25+
26+
@pytest.mark.parametrize(
27+
("operacao", "transformacao_no_histograma"),
28+
[
29+
(lambda medida: medida + 3, lambda amostras: amostras + 3),
30+
(lambda medida: 3 + medida, lambda amostras: 3 + amostras),
31+
(lambda medida: medida - 3, lambda amostras: amostras - 3),
32+
(lambda medida: 3 - medida, lambda amostras: 3 - amostras),
33+
(lambda medida: medida * -3, lambda histograma: histograma * -3),
34+
(lambda medida: medida / -3, lambda histograma: histograma / -3),
35+
(lambda medida: -medida, lambda histograma: -histograma),
36+
(lambda medida: abs(medida), lambda histograma: abs(histograma)),
37+
(lambda medida: +medida, lambda histograma: histograma),
38+
],
39+
)
40+
def test_operacoes_exatas_transformam_cada_amostra_do_histograma(
41+
operacao: Callable[[lab.Medida], lab.Medida],
42+
transformacao_no_histograma: Callable[[NDArray[np.float64]], NDArray[np.float64]],
43+
) -> None:
44+
medida = lab.Medida(-5, "m", 0.1)
45+
histograma_original = medida.histograma
46+
assert isinstance(histograma_original, Quantity)
47+
48+
histograma_resultado = operacao(medida).histograma
49+
assert isinstance(histograma_resultado, Quantity)
50+
np.testing.assert_allclose(
51+
histograma_resultado.magnitude,
52+
transformacao_no_histograma(histograma_original.magnitude),
4153
)
42-
w = lab.Medida(0, "", 0.1)
43-
assert (
44-
lab.comparar_medidas(w * x, nao_correlacionado) == lab.Comparacao.EQUIVALENTES
45-
)
46-
47-
48-
def test_multiplicacao_cte():
49-
x = lab.Medida(5, "", 0.1)
50-
y = 3 * x
51-
assert_medida_proxima(y, 15, 0.3)
52-
y = (-3) * x
53-
assert_medida_proxima(y, -15, 0.3)
54-
55-
y = x * 3
56-
assert_medida_proxima(y, 15, 0.3)
57-
y = x * (-3)
58-
assert_medida_proxima(y, -15, 0.3)
59-
60-
61-
def test_mudanca_de_sinal():
62-
x = lab.Medida(5, "", 0.1)
63-
y = -x
64-
assert y.nominal("") == -5 and y.incerteza("") == 0.1
65-
assert x.nominal("") == 5 and x.incerteza("") == 0.1 # cria uma cópia
66-
y = abs(y)
67-
assert y.nominal("") == 5 and y.incerteza("") == 0.1
68-
w = abs(x / y)
69-
assert np.isclose(w.nominal(""), 1, rtol=1e-3)
70-
71-
z = +w
72-
for i in range(len(z.histograma)):
73-
assert z.histograma[i] == w.histograma[i]
74-
w._nominal = 3
75-
assert not isinstance(z._nominal, int) # cria uma cópia
76-
7754

78-
def test_divisao():
79-
x = lab.Medida(-3, "", 0.1)
80-
correlacao = x / x
81-
assert correlacao.nominal("") == 1 and correlacao.incerteza("") == 0
8255

83-
x = lab.Medida(5, "", 0.1)
84-
assert (x / 5).nominal("") == 1 and (x / 5).incerteza("") == 0.1 / 5
85-
86-
y = lab.Medida(-3, "", 0.1)
87-
assert (x / y).incerteza("") != 0
88-
89-
assert np.isclose((10 / x).nominal(""), 2, 1e-3)
90-
91-
divisao = (y / x).nominal("")
92-
divisao_inversa = (x / y).nominal("")
93-
assert np.isclose(divisao, 1 / divisao_inversa, rtol=1e-2)
94-
95-
with pytest.raises(TypeError):
96-
"3" / lab.Medida(0, "", 0.1)
97-
98-
99-
def test_divisoes_especiais_nao_existe():
100-
statements = [lambda x, y: x // y, lambda x, y: x % y, lambda x, y: divmod(x, y)]
101-
with pytest.raises(TypeError):
102-
for statement in statements:
103-
statement(lab.Medida(6, "", 0.1), lab.Medida(1, "", 0.1))
104-
105-
106-
def test_potencia():
107-
x = lab.Medida(2, "", 0.01)
108-
y = lab.Medida(6, "", 0.01)
109-
assert np.isclose((x**3).nominal(""), 8, 1e-3)
110-
assert np.isclose((2**x).nominal(""), 4, 1e-3)
111-
assert np.isclose((x**y).nominal(""), 64, 1e-2)
112-
assert (x**y).incerteza("") > (x**2).incerteza("")
113-
assert np.isclose((x**-20).nominal(""), 1 / (2**20), 1e-3)
56+
@pytest.mark.parametrize(
57+
"operacao",
58+
[
59+
lambda medida: "3" / medida,
60+
lambda medida: medida ** "3",
61+
lambda medida: "3" ** medida,
62+
lambda medida: medida // 2,
63+
lambda medida: medida % 2,
64+
lambda medida: divmod(medida, 2),
65+
],
66+
)
67+
def test_operacoes_nao_suportadas_levantam_type_error(
68+
operacao: Callable[[lab.Medida], object],
69+
) -> None:
11470
with pytest.raises(TypeError):
115-
lab.Medida(0, "", 0.1) ** "3"
116-
with pytest.raises(TypeError):
117-
"3" ** lab.Medida(0, "", 0.1)
118-
119-
120-
def test_soma_subtracao_constante_histograma():
121-
x = lab.Medida(5, "m", 0.1)
122-
h_x = x.histograma
123-
124-
y = x + 3.0
125-
h_y = y.histograma
126-
127-
z = x - 2.0
128-
h_z = z.histograma
129-
130-
assert np.allclose(h_y.magnitude - h_x.magnitude, 3.0)
131-
assert np.allclose(h_z.magnitude - h_x.magnitude, -2.0)
71+
operacao(lab.Medida(6, "", 0.1))
72+
73+
74+
OperacaoVetorizada = Callable[[lab.Medida, NDArray[np.object_]], NDArray[np.object_]]
75+
OperacaoEscalar = Callable[[lab.Medida, lab.Medida], lab.Medida]
76+
77+
78+
@pytest.mark.parametrize(
79+
("operacao_vetorizada", "operacao_elemento"),
80+
[
81+
(lambda escalar, array: escalar + array, lambda escalar, item: escalar + item),
82+
(lambda escalar, array: array + escalar, lambda escalar, item: item + escalar),
83+
(lambda escalar, array: escalar - array, lambda escalar, item: escalar - item),
84+
(lambda escalar, array: array - escalar, lambda escalar, item: item - escalar),
85+
(lambda escalar, array: escalar * array, lambda escalar, item: escalar * item),
86+
(lambda escalar, array: array * escalar, lambda escalar, item: item * escalar),
87+
(lambda escalar, array: escalar / array, lambda escalar, item: escalar / item),
88+
(lambda escalar, array: array / escalar, lambda escalar, item: item / escalar),
89+
(lambda escalar, array: escalar**array, lambda escalar, item: escalar**item),
90+
(lambda escalar, array: array**escalar, lambda escalar, item: item**escalar),
91+
],
92+
)
93+
def test_operacoes_entre_medida_e_array_sao_elemento_a_elemento(
94+
operacao_vetorizada: OperacaoVetorizada,
95+
operacao_elemento: OperacaoEscalar,
96+
) -> None:
97+
escalar = lab.Medida(2, "", 0.01)
98+
medidas = lab.arrayM([1, 2, 4], "", 0.02)
99+
100+
resultado = operacao_vetorizada(escalar, medidas)
101+
102+
assert isinstance(resultado, np.ndarray)
103+
assert resultado.shape == medidas.shape
104+
assert resultado.dtype == object
105+
for obtido, item in zip(resultado, medidas, strict=True):
106+
assert isinstance(obtido, lab.Medida)
107+
esperado = operacao_elemento(escalar, item)
108+
assert_medida_proxima(
109+
obtido,
110+
esperado.nominal(""),
111+
esperado.incerteza(""),
112+
rtol=1e-3,
113+
atol=1e-6,
114+
)

tests/medida/test_funcoes_vetorizadas.py

Lines changed: 0 additions & 61 deletions
This file was deleted.

0 commit comments

Comments
 (0)