Skip to content

Commit

Permalink
Migrate common model and notebook functionality in from boilerdata
Browse files Browse the repository at this point in the history
  • Loading branch information
blakeNaccarato committed Aug 29, 2023
1 parent a63fa6b commit c027a49
Show file tree
Hide file tree
Showing 8 changed files with 107 additions and 38 deletions.
4 changes: 4 additions & 0 deletions .tools/requirements/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
# Latest working requirements of your package, should be ahead of pyproject.toml.
IPython[notebook]==8.14.0
pandas[hdf5,performance]==2.0.2
pandas-stubs~=2.0.2
ploomber-engine==0.0.30
pydantic==1.10.12
ruamel.yaml==0.17.32
scipy==1.11.1
sympy==1.12
# Numba only supports numpy<1.25 https://github.com/numba/numba/issues/8698
# ! Unpin numba once it supports numpy>=1.25
numba==0.57.1
Expand Down
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,13 @@ license = { file = "LICENSE" }
requires-python = ">=3.11"
classifiers = ["License :: OSI Approved :: MIT License"]
dependencies = [
"IPython[notebook]>=8.14.0",
"pandas[hdf5,performance]>=2.0.2",
"ploomber-engine>=0.0.30",
"pydantic>=1.10.12,<2",
"ruamel.yaml>=0.17.32",
"scipy>=1.11.1",
"sympy>=1.12",
# Numba only supports numpy<1.25 https://github.com/numba/numba/issues/8698
# ! Unpin numba once it supports numpy>=1.25
"numba>=0.57.1",
Expand Down
2 changes: 2 additions & 0 deletions src/boilercore/fits.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
"""Model fits."""

import warnings
from collections.abc import Mapping, Sequence
from functools import partial
Expand Down
2 changes: 1 addition & 1 deletion src/boilercore/models.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""Basic models for this project."""
"""Basic models."""

from collections.abc import Mapping, Sequence
from pathlib import Path
Expand Down
41 changes: 41 additions & 0 deletions src/boilercore/notebooks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
"""Notebook helpers."""

from typing import Any

import pandas as pd
from IPython.core.display import Markdown, Math
from IPython.display import display
from sympy import FiniteSet
from sympy.printing.latex import latex


def set_format():
"""Set up formatting for interactive notebook sessions.
The triple curly braces in the f-string allows the format function to be dynamically
specified by a given float specification. The intent is clearer this way, and may be
extended in the future by making `float_spec` a parameter.
"""
float_spec = ":#.4g"
pd.options.display.min_rows = pd.options.display.max_rows = 50
pd.options.display.float_format = f"{{{float_spec}}}".format


def disp_named(*args: tuple[Any, str]):
"""Display objects with names above them."""
for elem, name in args:
display(Markdown(f"##### {name}"))
display(elem)


def disp_free(title, eqn, **kwargs):
disp(title, eqn, **kwargs)
disp("Free symbols", FiniteSet(*eqn.rhs.free_symbols), **kwargs)


def disp(title, *exprs, **kwargs):
print(f"{title}:")
display(*(math_mod(expr, **kwargs) for expr in exprs))


def math_mod(expr, long_frac_ratio=3, **kwargs):
return Math(latex(expr, long_frac_ratio=long_frac_ratio, **kwargs))
54 changes: 54 additions & 0 deletions src/boilercore/paths.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
"""Paths and modules."""

from collections.abc import Iterable
from pathlib import Path
from re import compile
from types import ModuleType


def get_package_dir(package: ModuleType) -> Path:
return Path(next(iter(package.__path__)))


def map_stages(stages_dir: Path, package_dir: Path) -> dict[str, Path]:
"""Map stage module names to their paths."""
stages: dict[str, Path] = {}
for path in walk_module_paths(stages_dir, package_dir, glob="[!__]*.[py ipynb]*"):
module = get_module_rel(get_module(path, package_dir), stages_dir.name)
stages[module.replace(".", "_")] = path
return stages


def walk_module_paths(
package: Path, top: Path, suffix: str = ".py", glob: str | None = None
) -> Iterable[Path]:
"""Walk modules from a given submodule path and the top level library directory."""
for directory in (
package,
*[
path
for path in package.iterdir()
if path.is_dir() and "__" not in str(path.relative_to(top.parent))
],
):
yield from sorted(directory.glob(glob or f"[!__]*{suffix}"))


def get_module(module: Path, package: Path) -> str:
"""Get module name given the submodule path and the top level library directory."""
return (
str(module.relative_to(package.parent).with_suffix(""))
.replace("\\", ".")
.replace("/", ".")
)


def walk_modules(package: Path, top: Path, suffix: str = ".py") -> Iterable[str]:
"""Walk modules from a given submodule path and the top level library directory."""
for module in walk_module_paths(package, top, suffix):
yield get_module(module, top)


def get_module_rel(module: str, relative: str) -> str:
"""Get module name relative to another module."""
return compile(rf".*{relative}\.").sub(repl="", string=module)
37 changes: 1 addition & 36 deletions src/boilercore/testing.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
"""Helper functions for testing boiler code."""
"""Test helpers."""

from collections.abc import Iterable
from contextlib import contextmanager
from pathlib import Path
from re import compile
from shutil import copy, copytree

import pytest
Expand Down Expand Up @@ -32,36 +30,3 @@ def before_tmp_workdir(tmp_path: Path, monkeypatch: pytest.MonkeyPatch):
yield
finally:
monkeypatch.chdir(tmp_path)


def walk_modules(package: Path, top: Path, suffix: str = ".py") -> Iterable[str]:
"""Walk modules from a given submodule path and the top level library directory."""
for module in walk_module_paths(package, top, suffix):
yield get_module(module, top)


def walk_module_paths(package: Path, top: Path, suffix: str = ".py") -> Iterable[Path]:
"""Walk modules from a given submodule path and the top level library directory."""
for directory in (
package,
*[
path
for path in package.iterdir()
if path.is_dir() and "__" not in str(path.relative_to(top.parent))
],
):
yield from sorted(directory.glob(f"[!__]*{suffix}"))


def get_module(submodule: Path, library: Path) -> str:
"""Get module name given the submodule path and the top level library directory."""
return (
str(submodule.relative_to(library.parent).with_suffix(""))
.replace("\\", ".")
.replace("/", ".")
)


def get_module_rel(module: str, relative: str) -> str:
"""Get module name relative to another module."""
return compile(rf".*{relative}\.").sub(repl="", string=module)
2 changes: 1 addition & 1 deletion src/boilercore/types.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""Types used throughout this package."""
"""Types."""

from typing import Literal, TypeVar

Expand Down

0 comments on commit c027a49

Please sign in to comment.