diff --git a/scripts/business_ch06_reconciliations_quality_control.py b/scripts/business_ch06_reconciliations_quality_control.py index af11d41..be55d1a 100644 --- a/scripts/business_ch06_reconciliations_quality_control.py +++ b/scripts/business_ch06_reconciliations_quality_control.py @@ -23,6 +23,8 @@ import pandas as pd +from pystatsv1.trackd.loaders import load_table + from scripts._cli import base_parser from scripts._business_recon import ( build_ar_rollforward, @@ -37,16 +39,11 @@ class Ch06Outputs: bank_exceptions: pd.DataFrame summary: dict[str, Any] -def _read_csv(path: Path) -> pd.DataFrame: - if not path.exists(): - raise FileNotFoundError(f"Missing required input: {path}") - return pd.read_csv(path) - def analyze_ch06(datadir: Path) -> Ch06Outputs: - gl = _read_csv(datadir / "gl_journal.csv") - tb = _read_csv(datadir / "trial_balance_monthly.csv") - ar_events = _read_csv(datadir / "ar_events.csv") - bank = _read_csv(datadir / "bank_statement.csv") + gl = load_table(datadir, "gl_journal.csv") + tb = load_table(datadir, "trial_balance_monthly.csv") + ar_events = load_table(datadir, "ar_events.csv") + bank = load_table(datadir, "bank_statement.csv") # AR rollforward tie-out diff --git a/scripts/business_ch08_descriptive_statistics_financial_performance.py b/scripts/business_ch08_descriptive_statistics_financial_performance.py index 30f54cc..5a519f6 100644 --- a/scripts/business_ch08_descriptive_statistics_financial_performance.py +++ b/scripts/business_ch08_descriptive_statistics_financial_performance.py @@ -40,6 +40,8 @@ import numpy as np import pandas as pd +from pystatsv1.trackd.loaders import load_table, resolve_datadir + from ._business_etl import build_gl_tidy_dataset from ._cli import base_parser @@ -54,18 +56,19 @@ class Ch08Outputs: def _read_csv_required(datadir: Path, filename: str, *, fallbacks: list[str] | None = None) -> pd.DataFrame: - """Read a required CSV, optionally trying fallback filenames. + """Read a required input CSV. - This keeps chapters robust when the simulator/export names evolve. + Uses Track D's shared loader so errors are consistent and beginner-friendly. + Supports a small list of fallback filenames for backward-compatibility. """ + root = resolve_datadir(datadir) candidates = [filename] + (fallbacks or []) for name in candidates: - path = datadir / name + path = root / name if path.exists(): - return pd.read_csv(path) - # If none found, raise using the primary expected name (so error is clear) - raise FileNotFoundError(datadir / filename) - + return load_table(root, name) + # Let the shared loader raise a friendly error for the primary expected name + return load_table(root, filename) def _pivot_statement(df: pd.DataFrame) -> pd.DataFrame: """Return a wide statement frame: index month, columns = line.""" @@ -481,4 +484,4 @@ def main(argv: list[str] | None = None) -> int: if __name__ == "__main__": - raise SystemExit(main()) + raise SystemExit(main()) \ No newline at end of file diff --git a/src/pystatsv1/assets/workbook_track_d.zip b/src/pystatsv1/assets/workbook_track_d.zip index 3ccb56f..9c72423 100644 Binary files a/src/pystatsv1/assets/workbook_track_d.zip and b/src/pystatsv1/assets/workbook_track_d.zip differ diff --git a/workbooks/track_d_template/scripts/business_ch06_reconciliations_quality_control.py b/workbooks/track_d_template/scripts/business_ch06_reconciliations_quality_control.py index 7ede31a..8021539 100644 --- a/workbooks/track_d_template/scripts/business_ch06_reconciliations_quality_control.py +++ b/workbooks/track_d_template/scripts/business_ch06_reconciliations_quality_control.py @@ -24,6 +24,8 @@ import pandas as pd +from pystatsv1.trackd.loaders import load_table + from scripts._cli import base_parser from scripts._business_recon import ( build_ar_rollforward, @@ -38,16 +40,11 @@ class Ch06Outputs: bank_exceptions: pd.DataFrame summary: dict[str, Any] -def _read_csv(path: Path) -> pd.DataFrame: - if not path.exists(): - raise FileNotFoundError(f"Missing required input: {path}") - return pd.read_csv(path) - def analyze_ch06(datadir: Path) -> Ch06Outputs: - gl = _read_csv(datadir / "gl_journal.csv") - tb = _read_csv(datadir / "trial_balance_monthly.csv") - ar_events = _read_csv(datadir / "ar_events.csv") - bank = _read_csv(datadir / "bank_statement.csv") + gl = load_table(datadir, "gl_journal.csv") + tb = load_table(datadir, "trial_balance_monthly.csv") + ar_events = load_table(datadir, "ar_events.csv") + bank = load_table(datadir, "bank_statement.csv") # AR rollforward tie-out diff --git a/workbooks/track_d_template/scripts/business_ch08_descriptive_statistics_financial_performance.py b/workbooks/track_d_template/scripts/business_ch08_descriptive_statistics_financial_performance.py index 97a824e..6471211 100644 --- a/workbooks/track_d_template/scripts/business_ch08_descriptive_statistics_financial_performance.py +++ b/workbooks/track_d_template/scripts/business_ch08_descriptive_statistics_financial_performance.py @@ -47,6 +47,8 @@ import numpy as np import pandas as pd +from pystatsv1.trackd.loaders import load_table, resolve_datadir + from ._business_etl import build_gl_tidy_dataset from ._cli import base_parser @@ -61,18 +63,19 @@ class Ch08Outputs: def _read_csv_required(datadir: Path, filename: str, *, fallbacks: list[str] | None = None) -> pd.DataFrame: - """Read a required CSV, optionally trying fallback filenames. + """Read a required input CSV. - This keeps chapters robust when the simulator/export names evolve. + Uses Track D's shared loader so errors are consistent and beginner-friendly. + Supports a small list of fallback filenames for backward-compatibility. """ + root = resolve_datadir(datadir) candidates = [filename] + (fallbacks or []) for name in candidates: - path = datadir / name + path = root / name if path.exists(): - return pd.read_csv(path) - # If none found, raise using the primary expected name (so error is clear) - raise FileNotFoundError(datadir / filename) - + return load_table(root, name) + # Let the shared loader raise a friendly error for the primary expected name + return load_table(root, filename) def _pivot_statement(df: pd.DataFrame) -> pd.DataFrame: """Return a wide statement frame: index month, columns = line.""" @@ -488,4 +491,4 @@ def main(argv: list[str] | None = None) -> int: if __name__ == "__main__": - raise SystemExit(main()) + raise SystemExit(main()) \ No newline at end of file