Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 36 additions & 10 deletions benchmarks/benchmarks/bench_intervals.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,27 @@

from asv_runner.benchmarks.mark import skip_params_if

from foapy import intervals
from foapy import chain_mode
from foapy.core import intervals_chain, intervals_tuple, tuple_mode

from .cases import best_case, dna_case, normal_case, worst_case

length = [5, 50, 500, 5000, 50000, 500000, 5000000, 50000000]

# mode integer values: 1=lossy, 2=normal, 3=cycle, 4=redundant
_CHAIN_MODE = {
1: chain_mode.boundary,
2: chain_mode.boundary,
3: chain_mode.cycle,
4: chain_mode.boundary,
}
_TUPLE_MODE = {
1: tuple_mode.lossy,
2: tuple_mode.normal,
3: tuple_mode.normal,
4: tuple_mode.redundant,
}

skip = [
(5000000, "Worst", 1, 1),
(5000000, "DNA", 1, 1),
Expand Down Expand Up @@ -81,10 +97,11 @@ class IntervalsSuite:
param_names = ["length", "case", "binding", "mode"]

data = None
mode = None
binding = None
chain_mode_val = None
tuple_mode_val = None
binding_val = None

def setup(self, length, case, binding, mode):
def setup(self, length, case, binding_int, mode_int):
if case == "Best":
self.data = best_case(length)
elif case == "DNA":
Expand All @@ -93,13 +110,22 @@ def setup(self, length, case, binding, mode):
self.data = normal_case(length)
elif case == "Worst":
self.data = worst_case(length)
self.mode = mode
self.binding = binding
self.binding_val = binding_int
self.chain_mode_val = _CHAIN_MODE[mode_int]
self.tuple_mode_val = _TUPLE_MODE[mode_int]

@skip_params_if(skip, os.getenv("QUICK_BENCHMARK") == "true")
def time_intervals(self, length, case, binding, mode):
intervals(self.data, self.binding, self.mode)
def time_intervals(self, length, case, binding_int, mode_int):
intervals_tuple(
intervals_chain(self.data, self.binding_val, self.chain_mode_val),
self.binding_val,
self.tuple_mode_val,
)

@skip_params_if(skip, os.getenv("QUICK_BENCHMARK") == "true")
def peakmem_intervals(self, length, case, binding, mode):
return intervals(self.data, self.binding, self.mode)
def peakmem_intervals(self, length, case, binding_int, mode_int):
return intervals_tuple(
intervals_chain(self.data, self.binding_val, self.chain_mode_val),
self.binding_val,
self.tuple_mode_val,
)
47 changes: 36 additions & 11 deletions benchmarks/benchmarks/bench_ma_intervals.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,27 @@

from asv_runner.benchmarks.mark import skip_params_if

from foapy.ma import intervals, order
from foapy import chain_mode
from foapy.core import tuple_mode
from foapy.ma import intervals_chain, intervals_tuple, order

from .ma_cases import best_case, dna_case, normal_case, worst_case

length = [5, 50, 500]
# , 5000, 50000, 500000, 5000000, 50000000

_CHAIN_MODE = {
1: chain_mode.boundary,
2: chain_mode.boundary,
3: chain_mode.cycle,
4: chain_mode.boundary,
}
_TUPLE_MODE = {
1: tuple_mode.lossy,
2: tuple_mode.normal,
3: tuple_mode.normal,
4: tuple_mode.redundant,
}

skip = [
(5000000, "Worst", 1, 1),
(5000000, "DNA", 1, 1),
Expand Down Expand Up @@ -81,10 +96,11 @@ class MaIntervalsSuite:
param_names = ["length", "case", "binding", "mode"]

data = None
mode = None
binding = None
chain_mode_val = None
tuple_mode_val = None
binding_val = None

def setup(self, length, case, binding, mode):
def setup(self, length, case, binding_int, mode_int):
if case == "Best":
self.data = order(best_case(length))
elif case == "DNA":
Expand All @@ -93,13 +109,22 @@ def setup(self, length, case, binding, mode):
self.data = order(normal_case(length))
elif case == "Worst":
self.data = order(worst_case(length))
self.mode = mode
self.binding = binding
self.binding_val = binding_int
self.chain_mode_val = _CHAIN_MODE[mode_int]
self.tuple_mode_val = _TUPLE_MODE[mode_int]

@skip_params_if(skip, os.getenv("QUICK_BENCHMARK") == "true")
def time_intervals(self, length, case, binding, mode):
intervals(self.data, self.binding, self.mode)
def time_intervals(self, length, case, binding_int, mode_int):
intervals_tuple(
intervals_chain(self.data, self.binding_val, self.chain_mode_val),
self.binding_val,
self.tuple_mode_val,
)

@skip_params_if(skip, os.getenv("QUICK_BENCHMARK") == "true")
def peakmem_intervals(self, length, case, binding, mode):
return intervals(self.data, self.binding, self.mode)
def peakmem_intervals(self, length, case, binding_int, mode_int):
return intervals_tuple(
intervals_chain(self.data, self.binding_val, self.chain_mode_val),
self.binding_val,
self.tuple_mode_val,
)
4 changes: 2 additions & 2 deletions benchmarks/benchmarks/bench_pipeline_full.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ def setup(self, length, case):

def time_pipeline_full(self, length, case):
chain = intervals_chain(self.data, binding.start, chain_mode.boundary)
result = intervals_tuple(chain, tuple_mode.normal)
result = intervals_tuple(chain, binding.start, tuple_mode.normal)
intervals_distribution(result)

def peakmem_pipeline_full(self, length, case):
chain = intervals_chain(self.data, binding.start, chain_mode.boundary)
result = intervals_tuple(chain, tuple_mode.normal)
result = intervals_tuple(chain, binding.start, tuple_mode.normal)
return intervals_distribution(result)
6 changes: 3 additions & 3 deletions docs/references/mode.md → docs/references/chain_mode.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
::: foapy.mode
::: foapy.chain_mode
options:
show_signature_annotations: false
members_order: source
Expand All @@ -7,11 +7,11 @@
show_symbol_type_heading: false
show_symbol_type_toc: false

::: foapy.mode
::: foapy.chain_mode
options:
show_root_heading: false
show_docstring_description: false
show_docstring_attributes: false
show_root_toc_entry: false
filters:
- foapy.mode
- foapy.chain_mode
1 change: 0 additions & 1 deletion docs/references/intervals.md

This file was deleted.

1 change: 1 addition & 0 deletions docs/references/intervals_chain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
::: foapy.intervals_chain
1 change: 1 addition & 0 deletions docs/references/intervals_distribution.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
::: foapy.intervals_distribution
1 change: 1 addition & 0 deletions docs/references/intervals_tuple.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
::: foapy.intervals_tuple
2 changes: 0 additions & 2 deletions docs/references/ma/intervals.md

This file was deleted.

1 change: 1 addition & 0 deletions docs/references/ma/intervals_chain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
::: foapy.ma.intervals_chain
1 change: 1 addition & 0 deletions docs/references/ma/intervals_distribution.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
::: foapy.ma.intervals_distribution
1 change: 1 addition & 0 deletions docs/references/ma/intervals_tuple.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
::: foapy.ma.intervals_tuple
17 changes: 17 additions & 0 deletions docs/references/tuple_mode.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
::: foapy.tuple_mode
options:
show_signature_annotations: false
members_order: source
show_docstring_examples: false
show_source: false
show_symbol_type_heading: false
show_symbol_type_toc: false

::: foapy.tuple_mode
options:
show_root_heading: false
show_docstring_description: false
show_docstring_attributes: false
show_root_toc_entry: false
filters:
- foapy.tuple_mode
11 changes: 8 additions & 3 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,19 @@ nav:
- "References":
- "foapy.alphabet": references/alphabet.md
- "foapy.order": references/order.md
- "foapy.intervals": references/intervals.md
- "foapy.binding": references/binding.md
- "foapy.mode": references/mode.md
- "foapy.chain_mode": references/chain_mode.md
- "foapy.tuple_mode": references/tuple_mode.md
- "foapy.intervals_chain": references/intervals_chain.md
- "foapy.intervals_tuple": references/intervals_tuple.md
- "foapy.intervals_distribution": references/intervals_distribution.md
- "foapy.ma":
- references/ma/index.md
- "alphabet": references/ma/alphabet.md
- "order": references/ma/order.md
- "intervals": references/ma/intervals.md
- "intervals_chain": references/ma/intervals_chain.md
- "intervals_tuple": references/ma/intervals_tuple.md
- "intervals_distribution": references/ma/intervals_distribution.md
- "foapy.characteristics":
- references/characteristics/index.md
- "arithmetic_mean": references/characteristics/arithmetic_mean.md
Expand Down
34 changes: 34 additions & 0 deletions specs/003-cleanup-intervals-pipeline/checklists/requirements.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Specification Quality Checklist: Cleanup Intervals Pipeline

**Purpose**: Validate specification completeness and quality before proceeding to planning
**Created**: 2026-04-19
**Feature**: [spec.md](../spec.md)

## Content Quality

- [x] No implementation details (languages, frameworks, APIs)
- [x] Focused on user value and business needs
- [x] Written for non-technical stakeholders
- [x] All mandatory sections completed

## Requirement Completeness

- [x] No [NEEDS CLARIFICATION] markers remain
- [x] Requirements are testable and unambiguous
- [x] Success criteria are measurable
- [x] Success criteria are technology-agnostic (no implementation details)
- [x] All acceptance scenarios are defined
- [x] Edge cases are identified
- [x] Scope is clearly bounded
- [x] Dependencies and assumptions identified

## Feature Readiness

- [x] All functional requirements have clear acceptance criteria
- [x] User scenarios cover primary flows
- [x] Feature meets measurable outcomes defined in Success Criteria
- [x] No implementation details leak into specification

## Notes

- All items pass. Spec is ready for `/speckit.plan`.
71 changes: 71 additions & 0 deletions specs/003-cleanup-intervals-pipeline/contracts/api-changes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# API Contract: Cleanup Intervals Pipeline

**Branch**: `003-cleanup-intervals-pipeline` | **Date**: 2026-04-19

## Public API Diff

### Removed from `foapy` namespace

```python
# REMOVED — raises ImportError after this change
from foapy import intervals # was: intervals(X, binding, mode) -> ndarray
from foapy import mode # was: mode.lossy / mode.normal / mode.cycle / mode.redundant
from foapy import is_valid_intervals_chain # was: is_valid_intervals_chain(chain) -> bool
```

### Removed from `foapy.ma` namespace

```python
# REMOVED — raises ImportError after this change
from foapy.ma import intervals # was: intervals(X, binding, mode) -> list[ndarray]
```

### Unchanged in `foapy` namespace

```python
from foapy import intervals_chain # intervals_chain(X, binding, chain_mode) -> ndarray
from foapy import intervals_tuple # intervals_tuple(chain, binding, tuple_mode) -> ndarray
from foapy import intervals_distribution # intervals_distribution(intervals_tuple) -> ndarray
from foapy import chain_mode # chain_mode.boundary | chain_mode.cycle
from foapy import tuple_mode # tuple_mode.lossy | tuple_mode.normal | tuple_mode.redundant
from foapy import binding # binding.start | binding.end
from foapy import order # order(X) -> ndarray
from foapy import alphabet # alphabet(X) -> ndarray
```

### Unchanged in `foapy.ma` namespace

```python
from foapy.ma import intervals_chain
from foapy.ma import intervals_tuple
from foapy.ma import intervals_distribution
from foapy.ma import order
from foapy.ma import alphabet
```

---

## Mode Mapping Reference

The following table documents the equivalence between the retired `mode` enum and the decomposed pipeline. This is the contract verified by the equivalence test module.

| Old call | Decomposed equivalent |
|----------|----------------------|
| `intervals(X, b, mode.lossy)` | `intervals_tuple(intervals_chain(X, b, chain_mode.boundary), b, tuple_mode.lossy)` |
| `intervals(X, b, mode.normal)` | `intervals_tuple(intervals_chain(X, b, chain_mode.boundary), b, tuple_mode.normal)` |
| `intervals(X, b, mode.cycle)` | `intervals_tuple(intervals_chain(X, b, chain_mode.cycle), b, tuple_mode.normal)` |
| `intervals(X, b, mode.redundant)` | `intervals_tuple(intervals_chain(X, b, chain_mode.boundary), b, tuple_mode.redundant)` |

---

## Test-Helper Availability

The retired `intervals()` functions are available **only** within the test suite:

```python
# Available in tests ONLY — not a public API
from tests.helpers.intervals import intervals, mode
from tests.helpers.ma_intervals import intervals as ma_intervals
```

These helpers MUST NOT be imported from any production source file.
Loading
Loading