Coverage for kataglyphis_webdavclient/dummy.py: 90%
42 statements
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-20 21:53 +0000
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-20 21:53 +0000
1# Copyright (c) 2024 Jonas Heinle
3"""Dummy ML preprocessing helpers used by tests and demos."""
5import numpy as np
6from loguru import logger
9class SimpleMLPreprocessor:
10 """Simple preprocessing pipeline for synthetic tabular data."""
12 def __init__(self, n_samples: int) -> None:
13 """Initialize the preprocessor state.
15 Args:
16 n_samples: Number of synthetic rows to generate.
17 """
18 self.n_samples = n_samples
19 self.features = np.array([])
20 self.labels = np.array([])
21 self.normalized = np.array([])
22 self.stats = {}
24 def generate_synthetic_data(self) -> tuple[np.ndarray, np.ndarray]:
25 """Generate synthetic feature vectors and binary labels."""
26 logger.debug(
27 f"Generating {self.n_samples} samples of synthetic features and labels..."
28 )
29 rng = np.random.default_rng()
30 self.features = rng.normal(loc=5.0, scale=2.0, size=(self.n_samples, 3))
31 self.labels = (self.features.sum(axis=1) > 15).astype(int)
32 logger.info(f"First 5 feature vectors: {self.features[:5]}")
33 logger.info(f"First 5 labels: {self.labels[:5]}")
34 return self.features, self.labels
36 def normalize_features(self) -> np.ndarray:
37 """Normalize features by mean and standard deviation per column."""
38 if self.features.size == 0:
39 logger.warning("No features to normalize.")
40 return np.array([])
42 mean = self.features.mean(axis=0)
43 std = self.features.std(axis=0)
44 self.normalized = (self.features - mean) / std
46 self.stats = {"mean": mean.tolist(), "std": std.tolist()}
47 logger.debug(f"Feature normalization stats: {self.stats}")
48 return self.normalized
50 def apply_joke_labeling(self) -> np.ndarray:
51 """Map numeric labels to playful text labels."""
52 if self.labels.size == 0:
53 logger.warning("No labels to convert into jokes.")
54 return np.array([])
56 jokes = np.where(self.labels == 1, "Definitely ML", "Possibly Not")
57 logger.info(f"First 5 joke labels: {jokes[:5]}")
58 return jokes
60 def run_pipeline(self) -> dict[str, object]:
61 """Execute the full preprocessing pipeline and return all outputs."""
62 logger.info(
63 f"Running ML preprocessing pipeline for {self.n_samples} samples..."
64 )
65 self.generate_synthetic_data()
66 self.normalize_features()
67 jokes = self.apply_joke_labeling()
69 result = {
70 "features": self.features,
71 "labels": self.labels,
72 "normalized": self.normalized,
73 **self.stats,
74 "joke_labels": jokes,
75 }
76 logger.success("ML pipeline complete!")
77 return result