# Why the Even-Sampling Algorithm Always Keeps First and Last Frames

> Discover why the even sampling algorithm guarantees first and last frame retention. Understand the mathematical mapping that ensures frame preservation for your video projects.

- Repository: [bradautomates/claude-video](https://github.com/bradautomates/claude-video)
- Tags: deep-dive
- Published: 2026-08-03

---

**The even-sampling algorithm guarantees first and last frame retention through a mathematical mapping in `_even_indices(count, n)` that scales index range `0 … n‑1` onto `0 … count‑1`, forcing `i=0 → 0` and `i=n‑1 → count‑1`.**

In the `bradautomates/claude-video` repository, the watch skill caps extracted frames using an even-sampling approach that never discards boundary frames. Understanding this behavior requires examining two carefully designed helper functions in [`skills/watch/scripts/frames.py`](https://github.com/bradautomates/claude-video/blob/main/skills/watch/scripts/frames.py) that work together to preserve visual continuity from start to finish.

## The Mathematical Foundation in `_even_indices`

The guarantee originates in `_even_indices(count, n)`, a pure-Python function at lines 283-293. This function computes which indices to select when reducing a list of `count` items down to `n` evenly spaced samples.

### How the Formula Forces Boundary Retention

When `n` is less than `count` and greater than 1, the function builds its result using a list comprehension:

```python
[round(i * (count - 1) / (n - 1)) for i in range(n)]

```

Two critical design decisions enforce first and last frame preservation:

1. **Numerator uses `count - 1`** — the maximum valid index
2. **Denominator uses `n - 1`** — the maximum iteration value

This creates a linear mapping where:
- At `i = 0`: `round(0 * (count-1) / (n-1)) = 0` → **first index**
- At `i = n-1`: `round((n-1) * (count-1) / (n-1)) = count - 1` → **last index**

The arithmetic ensures these boundary positions are **mathematically inescapable** in the output, regardless of `count` or `n` values.

### Edge Case Handling

The function covers three scenarios in [`skills/watch/scripts/frames.py`](https://github.com/bradautomates/claude-video/blob/main/skills/watch/scripts/frames.py):

| Condition | Behavior | Result |
|-----------|----------|--------|
| `n >= count` | Returns `list(range(count))` | All items kept |
| `n == 1` | Returns `[0]` | Only first item |
| `1 < n < count` | Applies spacing formula | First and last always included |

## Application Through `_even_sample`

The second function, `_even_sample(candidates, n)` at lines 393-402, applies the index selection to actual frame objects. Its implementation is direct:

```python
selected = [candidates[i] for i in _even_indices(len(candidates), n)]

```

Because `_even_indices` always includes indices `0` and `len(candidates)-1`, the first and last candidates survive the capping process. The function then deletes JPEG files for dropped candidates and re-indexes survivors to maintain clean sequence numbers.

## Usage Contexts in Frame Extraction

Even-sampling with first/last preservation triggers whenever frame candidates exceed configured limits:

- **Keyframe extraction** — when detected I-frames outnumber `max_frames`
- **Scene detection** — when segment boundaries produce too many candidates
- **Timestamp cues** — when dense timestamp lists request more frames than allowed

The deterministic output ensures summaries remain visually anchored to content boundaries, preventing arbitrary truncation that could miss opening titles or closing credits.

## Code Examples

### Direct Even-Sampling Demonstration

```python
from pathlib import Path
from skills.watch.scripts.frames import _even_sample

# Simulated list of 10 frame candidates

candidates = [
    {"index": i, "timestamp_seconds": i * 0.5, "path": f"/tmp/frame_{i:04d}.jpg"}
    for i in range(10)
]

# Cap to 4 frames → we expect frames 0, 3, 6, 9 (first & last kept)

selected = _even_sample(candidates, 4)

print([f["index"] for f in selected])

# Output: [0, 3, 6, 9]

```

### Frame Extraction with Automatic Capping

```python
from skills.watch.scripts.frames import extract_at_timestamps

# Request many cues but cap to 5 frames

frames, meta = extract_at_timestamps(
    video_path="video.mp4",
    out_dir=Path("/tmp/cues"),
    timestamps=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
    max_frames=5,               # cap triggers even-sampling

)

print(meta["selected_count"])   # → 5, with first & last timestamps kept

```

## Source Code References

| File | Lines | Purpose |
|------|-------|---------|
| [`skills/watch/scripts/frames.py`](https://github.com/bradautomates/claude-video/blob/main/skills/watch/scripts/frames.py) | 283-293 | `_even_indices()` — index computation with boundary guarantees |
| [`skills/watch/scripts/frames.py`](https://github.com/bradautomates/claude-video/blob/main/skills/watch/scripts/frames.py) | 393-402 | `_even_sample()` — candidate filtering and file cleanup |
| [`tests/test_frames.py`](https://github.com/bradautomates/claude-video/blob/main/tests/test_frames.py) | Various | Validates capping behavior and boundary preservation |
| [`tests/test_timestamps.py`](https://github.com/bradautomates/claude-video/blob/main/tests/test_timestamps.py) | Various | Confirms timestamp extraction respects first/last retention |

## Summary

- **Mathematical certainty**: The `(count-1)/(n-1)` scaling factor in `_even_indices` mathematically forces indices 0 and `count-1` into every result
- **Clean abstraction**: `_even_sample` delegates index selection entirely to `_even_indices`, inheriting its guarantees without duplication
- **Consistent application**: All frame-capping paths in the watch skill use this unified approach
- **Test coverage**: The test suite explicitly verifies first and last frame retention across multiple scenarios

## Frequently Asked Questions

### What happens if I request only 1 frame from a large candidate set?

When `n == 1`, `_even_indices` returns `[0]` — the first frame only. The single-frame case deliberately prioritizes the opening visual over the closing frame, as implemented at line 286 in [`skills/watch/scripts/frames.py`](https://github.com/bradautomates/claude-video/blob/main/skills/watch/scripts/frames.py).

### Does even-sampling run if candidates are already under the limit?

No. The algorithm short-circuits when `n >= count`, returning all indices unchanged. This avoids unnecessary computation and preserves exact frames when capacity permits.

### Can the boundary retention behavior be disabled?

Not through configuration. The guarantee is hardcoded in the arithmetic of `_even_indices`. To modify this behavior would require forking and altering the formula at line 293 of [`skills/watch/scripts/frames.py`](https://github.com/bradautomates/claude-video/blob/main/skills/watch/scripts/frames.py).

### Why use `round()` instead of `floor()` or integer division?

The `round()` function produces the most accurate approximation to true even spacing. Integer division would bias selections toward lower indices, while `floor()` could create clustering artifacts. The symmetric rounding better distributes frames across the full temporal range while maintaining the essential first/last guarantee.