Skip to content

Add allocate_from_rows: from a table of per-period counts to an allocation - #19

Merged
sulgik merged 2 commits into
mainfrom
warehouse-helpers
Oct 7, 2026
Merged

sulgik merged 2 commits into
mainfrom
warehouse-helpers

Conversation

@sulgik

@sulgik sulgik commented Oct 7, 2026

Copy link
Copy Markdown
Owner

What

A scheduled job keeps no state between runs: it reads the experiment's history from a table and needs the next allocation. This adds that path.

  • allocate_from_rows(rows, ...) returns an Allocation; allocate_cells_from_rows returns {cell: Allocation} from the experimental contextual model. batches_from_rows and replay are the two steps inside.
  • Rows may be dicts, sqlite3.Row objects, or a pandas or polars frame, without importing either library.
  • The periods are folded in sorted order and arms and cells in name order, so the result depends only on the table. seed makes a run reproducible.
  • examples/sql/period_counts.sql builds the table from an exposure log and a conversion log, and examples/from_warehouse.py runs it end to end on SQLite.
  • README sections in English and Korean, examples index, CHANGELOG under Unreleased.

SQL choices

Each user is counted once, in the period of their first exposure, and a user seen in two variations is dropped. The conversion window is fixed, and a user whose window is still open is left out. That filter depends on when the user was exposed, never on what they did, so it does not bias the rates. Only the SQLite version is tested; the three dialect-specific spots are marked in the file.

Tests

tests/test_history.py: the helpers equal the manual fold, row order and table type do not matter, bad tables are rejected with a reason, and the SQL is run against hand-built edge cases (double exposure, open window, conversion before exposure, conversion after the window, repeated conversions, another experiment).

Not merged yet

The README on main would describe functions that the released 2.4.0 does not have, so this should merge together with the release that ships them.

🤖 Generated with Claude Code

sulgik and others added 2 commits October 7, 2026 17:03
…ation

A scheduled job keeps no state between runs; it reads the history from a
table and needs the next allocation. allocate_from_rows,
allocate_cells_from_rows, batches_from_rows and replay do that, folding the
periods in sorted order and arms and cells in name order so the result
depends only on the table. Rows may be dicts, sqlite3 rows, or pandas or
polars frames.

examples/sql/period_counts.sql builds the table from an exposure log and a
conversion log: one count per user, in the period of the first exposure, a
fixed window, users with an open window left out. It is tested on SQLite
against hand-built edge cases, and examples/from_warehouse.py runs it end
to end. README sections in English and Korean.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@sulgik
sulgik merged commit 697836f into main Oct 7, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant