Skip to content

Commit e743787

Browse files
committed
Test handling of duplicate defaultvalues
1 parent 5eee096 commit e743787

3 files changed

Lines changed: 35 additions & 27 deletions

File tree

src/semeio/fmudesign/_excel2dict.py

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
read by semeio.fmudesign.DesignMatrix.generate
44
"""
55

6+
import logging
67
from collections import OrderedDict
78
from collections.abc import Mapping
89
from typing import Any
@@ -12,6 +13,8 @@
1213
import pandas as pd
1314
import yaml
1415

16+
logger = logging.getLogger(__name__)
17+
1518

1619
def excel2dict_design(
1720
input_filename: str, sheetnames: Mapping[str, Any] | None = None
@@ -382,34 +385,34 @@ def _read_defaultvalues(filename: str, sheetname: str) -> OrderedDict[str, Any]:
382385
Returns:
383386
OrderedDict with defaultvalues (parameter, value)
384387
"""
385-
default_dict: OrderedDict[str, Any] = OrderedDict()
386388
default_df = pd.read_excel(
387389
filename, sheetname, header=0, index_col=0, engine="openpyxl"
388390
)
391+
389392
default_df.dropna(axis=0, how="all", inplace=True)
390393
default_df = default_df.loc[
391394
:, ~default_df.columns.astype(str).str.contains("^Unnamed")
392395
]
393396

394-
# Strip spaces before and after parameter names, if they are there
395-
# it is probably invisible user errors in Excel.
396-
397-
default_df.index = pd.Index(
398-
[
399-
paramname.strip() if isinstance(paramname, str) else paramname
400-
for paramname in default_df.index
401-
]
402-
)
403-
for row in default_df.itertuples():
404-
if str(row[0]) in default_dict:
405-
print(
406-
f"WARNING: The default value '{row[0]}' "
407-
f"is listed twice in the sheet '{sheetname}'. "
408-
"Only the first entry will be used in output file"
397+
if default_df.empty:
398+
return OrderedDict()
399+
400+
# Strip leading/trailing spaces from parameter names such that
401+
# for example " PARAM" and "PARAM" are treated as duplicates.
402+
default_df.index = default_df.index.str.strip()
403+
404+
# Check for duplicates and warn
405+
duplicates = default_df.index.duplicated(keep="first")
406+
if duplicates.any():
407+
duplicate_names = default_df.index[duplicates].unique()
408+
for dup_name in duplicate_names:
409+
logger.warning(
410+
f"The default value '{dup_name}' is listed twice in the sheet "
411+
f"'{sheetname}'. Only the first entry will be used in output file"
409412
)
410-
else:
411-
default_dict[str(row[0])] = row[1]
412-
return default_dict
413+
414+
default_df = default_df[~duplicates]
415+
return OrderedDict(default_df.iloc[:, 0].to_dict())
413416

414417

415418
def _read_dependencies(
180 Bytes
Binary file not shown.

tests/fmudesign/test_create_design.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""Testing code for generation of design matrices"""
22

33
import json
4+
import logging
45
import shutil
56
from datetime import datetime
67
from pathlib import Path
@@ -187,33 +188,37 @@ def test_generate_onebyone(tmpdir):
187188
pytest.fail("Timestamp in Metadata sheet is not in expected format")
188189

189190

190-
def test_generate_full_mc_snapshot(snapshot):
191+
def test_generate_full_mc_snapshot(snapshot, caplog):
191192
"""Test that full monte carlo design matrix generation remains consistent.
192-
193193
This is a snapshot test that verifies the entire output of the design matrix
194194
generation process, including both the design values and default values.
195195
"""
196196
# Setup
197197
inputfile = TESTDATA / "config/design_input_mc_with_correls.xlsx"
198-
input_dict = excel2dict_design(inputfile)
199-
design = DesignMatrix()
200198

201-
# Generate the design matrix
202-
design.generate(input_dict)
199+
with caplog.at_level(logging.WARNING):
200+
input_dict = excel2dict_design(inputfile)
201+
design = DesignMatrix()
202+
# Generate the design matrix
203+
design.generate(input_dict)
204+
205+
# Check that the warning was logged
206+
assert (
207+
"The default value 'FAULTSEAL' is listed twice in the sheet 'defaultvalues'"
208+
in caplog.text
209+
)
203210

204211
# Prepare data for snapshot comparison
205212
snapshot_dict = {
206213
"designvalues": design.designvalues.to_dict("records"),
207214
"defaultvalues": dict(design.defaultvalues),
208215
}
209-
210216
# Serialize to string for snapshot comparison
211217
snapshot_str = json.dumps(
212218
snapshot_dict,
213219
indent=2,
214220
sort_keys=True,
215221
)
216-
217222
# Verify against snapshot
218223
snapshot.assert_match(snapshot_str, "design_output_mc_with_correls.json")
219224

0 commit comments

Comments
 (0)