15
15
def generate_sample_data (
16
16
n_tags : int = 1 , n_runs : int = 10 , n_steps : int = 5
17
17
) -> dict [str , pd .DataFrame ]:
18
+ """Generate sample test data for testing reduce operations."""
18
19
events_dict = {}
19
20
rng = np .random .default_rng ()
20
21
for idx in range (n_tags ):
@@ -32,6 +33,7 @@ def test_reduce_events(
32
33
verbose : bool ,
33
34
capsys : pytest .CaptureFixture [str ],
34
35
) -> None :
36
+ """Test reduce_events with sequence of operations."""
35
37
reduced_events = reduce_events (events_dict , reduce_ops , verbose = verbose )
36
38
37
39
out_keys = list (reduced_events )
@@ -41,17 +43,17 @@ def test_reduce_events(
41
43
)
42
44
43
45
# loop over reduce operations
44
- for (op , out_dict ), in_arr in zip (
45
- reduced_events .items (), events_dict .values (), strict = True
46
- ):
47
- n_steps = len (in_arr ) # length of TB logs
46
+ for op in reduce_ops :
47
+ out_dict = reduced_events [op ]
48
48
49
- # loop over event tags (only 'strict/foo' here )
49
+ # loop over event tags (e.g., 'strict/foo')
50
50
for tag , out_arr in out_dict .items ():
51
51
assert tag in events_dict , (
52
52
f"unexpected key { tag } in reduced event dict[{ op } ] = { list (out_dict )} "
53
53
)
54
54
55
+ in_arr = events_dict [tag ]
56
+ n_steps = len (in_arr ) # length of TB logs
55
57
out_steps = len (out_arr )
56
58
57
59
assert n_steps == out_steps , (
@@ -76,8 +78,36 @@ def test_reduce_events(
76
78
assert stdout == ""
77
79
78
80
81
+ @pytest .mark .parametrize ("reduce_op" , ["mean" , "std" , "max" ])
82
+ def test_reduce_events_reduce_op_str_list_equivalence (reduce_op : str ) -> None :
83
+ """Test string input (fixes issue #44) and equivalence with list input."""
84
+ events_dict = generate_sample_data (n_tags = 2 , n_runs = 3 , n_steps = 4 )
85
+
86
+ # Test string input
87
+ result_string = reduce_events (events_dict , reduce_op )
88
+
89
+ # Test list input
90
+ result_list = reduce_events (events_dict , [reduce_op ])
91
+
92
+ # Verify string input structure and correctness
93
+ assert len (result_string ) == 1
94
+ assert reduce_op in result_string
95
+ for tag , df in events_dict .items ():
96
+ assert tag in result_string [reduce_op ]
97
+ expected = getattr (df , reduce_op )(axis = 1 )
98
+ pd .testing .assert_series_equal (result_string [reduce_op ][tag ], expected )
99
+
100
+ # Verify string and list inputs produce identical results
101
+ assert result_string .keys () == result_list .keys ()
102
+ for tag in events_dict :
103
+ pd .testing .assert_series_equal (
104
+ result_string [reduce_op ][tag ], result_list [reduce_op ][tag ]
105
+ )
106
+
107
+
79
108
@pytest .mark .parametrize ("n_tags, n_runs, n_steps" , [(1 , 10 , 5 ), (2 , 5 , 3 ), (3 , 3 , 10 )])
80
109
def test_reduce_events_dimensions (n_tags : int , n_runs : int , n_steps : int ) -> None :
110
+ """Test reduce_events with different data dimensions."""
81
111
events_dict = generate_sample_data (n_tags = n_tags , n_runs = n_runs , n_steps = n_steps )
82
112
reduce_ops = ["mean" , "std" , "max" , "min" ]
83
113
reduced_events = reduce_events (events_dict , reduce_ops )
@@ -97,5 +127,6 @@ def test_reduce_events_dimensions(n_tags: int, n_runs: int, n_steps: int) -> Non
97
127
98
128
@pytest .mark .parametrize ("reduce_ops" , [["mean" ], ["max" , "min" ], ["std" , "median" ]])
99
129
def test_reduce_events_empty_input (reduce_ops : Sequence [str ]) -> None :
130
+ """Test reduce_events with empty input dictionary."""
100
131
reduced_events = reduce_events ({}, reduce_ops )
101
132
assert reduced_events == {op : {} for op in reduce_ops }
0 commit comments