SIENTIAPDE-1430: Remove verbose options and direct print statements from model, preprocessor, and report utilities.

This commit is contained in:
Bruno Domingues
2025-12-18 21:09:12 -03:00
parent 13941fc3f7
commit 38fb9a9c53
4 changed files with 13 additions and 89 deletions

View File

@@ -43,7 +43,6 @@ class LinearRegressionModel(BaseEstimator, TransformerMixin):
weights: dict[str, float] | None = None,
degree: int = 1,
interaction_only: bool = False,
verbose: bool = False,
):
"""
Linear Regression Model for Time Series Analysis
@@ -58,7 +57,6 @@ class LinearRegressionModel(BaseEstimator, TransformerMixin):
*Format: {'variable_name': weight}*
degree (int): The degree of the polynomial features (1 = linear, >1 = polynomial)
interaction_only (bool): If True, only interaction features are produced
verbose (bool): If True, print verbose output during fitting
Returns:
LinearRegressionModel: The prediction model object
@@ -73,7 +71,6 @@ class LinearRegressionModel(BaseEstimator, TransformerMixin):
self.weights: dict[str, float] | None = weights
self.degree: int = degree
self.interaction_only: bool = interaction_only
self.verbose: bool = verbose
self.poly: PolynomialFeatures | None = None
self.poly_feature_names: list[str] | None = None
@@ -152,8 +149,6 @@ class LinearRegressionModel(BaseEstimator, TransformerMixin):
# Remove columns with all NaN values
cols_to_drop = X_train.columns[X_train.isna().all()].tolist()
if cols_to_drop: # pragma: no cover
if self.verbose:
print(f'Dropping columns with all NaN values: {cols_to_drop}')
X_train = X_train.drop(columns=cols_to_drop)
self.variable_columns = [c for c in self.variable_columns if c not in cols_to_drop]
@@ -163,8 +158,6 @@ class LinearRegressionModel(BaseEstimator, TransformerMixin):
# Apply polynomial features if degree > 1
if self.degree > 1:
X_train = self.create_poly_features(X_train, fit=True)
if self.verbose and self.poly_feature_names is not None:
print(f'Created {len(self.poly_feature_names)} polynomial features')
# Fit the model
self.regr.fit(X_train, y_train)
@@ -181,9 +174,6 @@ class LinearRegressionModel(BaseEstimator, TransformerMixin):
weights = {'Bias': float(round_intercept), **weights}
self.weights = weights
if self.verbose and feature_names is not None:
print(f'Model fitted with {len(feature_names)} features')
return self
def predict(self, input_data: pd.DataFrame) -> np.ndarray:
@@ -266,7 +256,6 @@ class DataPreprocessor(BaseEstimator, TransformerMixin):
cross_operations: list[str] | None = None,
created_lags: dict[str, int] | None = None,
steps_order: list[str] | None = None,
verbose: bool = False,
):
"""
Data Preprocessor for Time Series Analysis
@@ -313,7 +302,6 @@ class DataPreprocessor(BaseEstimator, TransformerMixin):
'Normalization',
'Feature Creation',
'Lag Creation'*
verbose (bool): If True, print verbose output during preprocessing
Returns:
DataPreprocessor: The data preprocessor object
@@ -338,7 +326,6 @@ class DataPreprocessor(BaseEstimator, TransformerMixin):
self.scaler_name = scaler_name
self.scaler_params = scaler_params
self.feature_names_order: list[str] = [] # Initialize to avoid AttributeError
self.verbose = verbose
self._fitted_feature_order: list[str] | None = None # Track feature order after fit
if self.scaler_name == 'Standard Scaler':
@@ -453,8 +440,6 @@ class DataPreprocessor(BaseEstimator, TransformerMixin):
if treatment == 'linear interpolation':
treatment = 'fill linear'
input_data = treat_nan(input_data, treatment)
if self.verbose:
print(f'Applied NaN treatment: {self.nan_treatment}')
return input_data
def range_selection(self, input_data: pd.DataFrame) -> pd.DataFrame:
@@ -472,8 +457,6 @@ class DataPreprocessor(BaseEstimator, TransformerMixin):
try:
start = pd.to_datetime(self.start_date)
input_data = input_data[input_data.index >= start]
if self.verbose:
print(f'Filtered data from start_date: {self.start_date}')
except (ValueError, TypeError):
pass # Invalid date format, skip filtering
@@ -481,8 +464,6 @@ class DataPreprocessor(BaseEstimator, TransformerMixin):
try:
end = pd.to_datetime(self.end_date)
input_data = input_data[input_data.index <= end]
if self.verbose:
print(f'Filtered data to end_date: {self.end_date}')
except (ValueError, TypeError):
pass # Invalid date format, skip filtering
@@ -498,8 +479,6 @@ class DataPreprocessor(BaseEstimator, TransformerMixin):
& (input_data.index <= interval_end)
)
input_data = input_data[mask]
if self.verbose:
print(f'Removed interval: {interval[0]} to {interval[1]}')
except (ValueError, TypeError):
pass # Invalid date format, skip this interval

View File

@@ -36,10 +36,8 @@ def load_html_from_file(file_path):
with open(file_path, encoding='utf-8') as file:
return file.read()
except FileNotFoundError:
print(f'File not found: {file_path}')
return None
except OSError as e: # noqa: BLE001
print(f'Error reading file: {e}')
except OSError: # noqa: BLE001
return None
@@ -49,8 +47,6 @@ def inject_content(main_html, section_id, content):
if section:
section.clear()
section.append(BeautifulSoup(content, 'html.parser'))
else:
print(f"Section with id '{section_id}' not found in the main HTML template.")
return str(soup)

View File

@@ -748,11 +748,9 @@ def test_linear_regression_model_fit_with_inf_values():
assert 'var2' in model.variable_columns
def test_linear_regression_model_fit_polynomial_verbose():
"""Test fit with polynomial features and verbose output."""
model = LinearRegressionModel(
target_variable='target', variable_columns=['var1'], degree=2, verbose=True
)
def test_linear_regression_model_fit_polynomial():
"""Test fit with polynomial features."""
model = LinearRegressionModel(target_variable='target', variable_columns=['var1'], degree=2)
data = pd.DataFrame({'var1': [1, 2, 3, 4, 5], 'target': [3, 5, 7, 9, 11]})
model.fit(data)
@@ -825,7 +823,7 @@ def test_linear_regression_model_get_regressor():
@patch('model_manager.sientia.models.treat_nan')
def test_data_preprocessor_treat_discontinuities_linear_interpolation(mock_treat_nan):
"""Test treat_discontinuities with 'linear interpolation' treatment."""
preprocessor = DataPreprocessor(nan_treatment='linear interpolation', verbose=True)
preprocessor = DataPreprocessor(nan_treatment='linear interpolation')
data = pd.DataFrame({'col1': [1, np.nan, 3]})
expected_data = pd.DataFrame({'col1': [1.0, 2.0, 3.0]})
mock_treat_nan.return_value = expected_data
@@ -839,7 +837,7 @@ def test_data_preprocessor_treat_discontinuities_linear_interpolation(mock_treat
def test_data_preprocessor_range_selection_with_start_date():
"""Test range_selection filters by start_date."""
preprocessor = DataPreprocessor(start_date='2023-01-02', verbose=True)
preprocessor = DataPreprocessor(start_date='2023-01-02')
data = pd.DataFrame(
{'col1': [1, 2, 3]},
index=pd.to_datetime(['2023-01-01', '2023-01-02', '2023-01-03']),
@@ -853,7 +851,7 @@ def test_data_preprocessor_range_selection_with_start_date():
def test_data_preprocessor_range_selection_with_end_date():
"""Test range_selection filters by end_date."""
preprocessor = DataPreprocessor(end_date='2023-01-02', verbose=True)
preprocessor = DataPreprocessor(end_date='2023-01-02')
data = pd.DataFrame(
{'col1': [1, 2, 3]},
index=pd.to_datetime(['2023-01-01', '2023-01-02', '2023-01-03']),
@@ -895,7 +893,7 @@ def test_data_preprocessor_range_selection_with_invalid_end_date():
def test_data_preprocessor_range_selection_with_removed_intervals():
"""Test range_selection removes specified intervals."""
preprocessor = DataPreprocessor(removed_intervals=[['2023-01-02', '2023-01-03']], verbose=True)
preprocessor = DataPreprocessor(removed_intervals=[['2023-01-02', '2023-01-03']])
data = pd.DataFrame(
{'col1': [1, 2, 3, 4, 5]},
index=pd.to_datetime(
@@ -999,51 +997,6 @@ def test_data_preprocessor_predict_preserves_feature_order():
# ============================================================================
def test_data_preprocessor_range_selection_start_date_non_verbose():
"""Test range_selection with start_date but verbose=False."""
preprocessor = DataPreprocessor(start_date='2023-01-02', verbose=False)
data = pd.DataFrame(
{'col1': [1, 2, 3]},
index=pd.to_datetime(['2023-01-01', '2023-01-02', '2023-01-03']),
)
result = preprocessor.range_selection(data)
assert len(result) == 2
assert result.index[0] == pd.Timestamp('2023-01-02')
def test_data_preprocessor_range_selection_end_date_non_verbose():
"""Test range_selection with end_date but verbose=False."""
preprocessor = DataPreprocessor(end_date='2023-01-02', verbose=False)
data = pd.DataFrame(
{'col1': [1, 2, 3]},
index=pd.to_datetime(['2023-01-01', '2023-01-02', '2023-01-03']),
)
result = preprocessor.range_selection(data)
assert len(result) == 2
assert result.index[-1] == pd.Timestamp('2023-01-02')
def test_data_preprocessor_range_selection_removed_intervals_non_verbose():
"""Test range_selection with removed_intervals but verbose=False."""
preprocessor = DataPreprocessor(removed_intervals=[['2023-01-02', '2023-01-03']], verbose=False)
data = pd.DataFrame(
{'col1': [1, 2, 3, 4, 5]},
index=pd.to_datetime(
['2023-01-01', '2023-01-02', '2023-01-03', '2023-01-04', '2023-01-05']
),
)
result = preprocessor.range_selection(data)
assert len(result) == 3
assert pd.Timestamp('2023-01-02') not in result.index
assert pd.Timestamp('2023-01-03') not in result.index
def test_data_preprocessor_predict_target_not_in_columns():
"""Test predict when target_variable is not in transformed data columns."""
preprocessor = DataPreprocessor(

View File

@@ -24,15 +24,13 @@ def test_load_html_from_file_success(tmp_path):
assert content == '<p>Hello</p>'
def test_load_html_from_file_missing_file(capsys):
def test_load_html_from_file_missing_file():
result = reports.load_html_from_file('non-existent.html')
captured = capsys.readouterr()
assert result is None
assert 'File not found: non-existent.html' in captured.out
def test_load_html_from_file_os_error(monkeypatch, capsys):
def test_load_html_from_file_os_error(monkeypatch):
def fake_open(*_args, **_kwargs):
raise OSError('boom')
@@ -40,9 +38,7 @@ def test_load_html_from_file_os_error(monkeypatch, capsys):
result = reports.load_html_from_file('path.html')
captured = capsys.readouterr()
assert result is None
assert 'Error reading file: boom' in captured.out
def test_inject_content_replaces_section():
@@ -57,15 +53,15 @@ def test_inject_content_replaces_section():
assert section.find('span').text == 'new'
def test_inject_content_missing_section(capsys):
def test_inject_content_missing_section():
main_html = "<html><body><div id='other'>keep</div></body></html>"
result = reports.inject_content(main_html, 'missing', '<p>ignored</p>')
captured = capsys.readouterr()
assert "Section with id 'missing' not found" in captured.out
# Content should be unchanged when section is missing
soup = BeautifulSoup(result, 'html.parser')
assert soup.find(id='other') is not None
assert soup.find(id='other').text == 'keep'
def test_reports_init_sets_defaults(stub_color_options):