StateTracker
StateTracker is a Python library for creating composable states with unidirectional value propagation. It provides a powerful way to enumerate combinatorial spaces through state algebra operations.
Why StateTracker?
StateTracker was developed to support the design of complex DNA sequence libraries (see PoolParty), but it solves a general problem: random access to combinatorial spaces.
If you've ever written nested loops to enumerate a Cartesian product and then wished you could shuffle the order, sample a subset, or split into train/test sets—all while tracking which component indices correspond to each item—StateTracker is for you. Build your combinatorial structure once using state algebra, and StateTracker handles the index math automatically.
Features
- Composable States: Build complex iteration patterns from simple states
- Unidirectional Value Propagation: Set child value and parent values update automatically
- State Algebra: Product (×), sum (+), slice, repeat, shuffle, and synchronize operations
- Conflict Detection: Automatic detection of conflicting value assignments
- Tree Visualization: Built-in ASCII tree visualization for debugging
Installation
pip install statetracker
For development:
git clone https://github.com/jbkinney/poolparty-statetracker.git
cd poolparty-statetracker/statetracker
pip install -e ".[dev]"
Quick Start
from statetracker import State, Manager, product, stack, repeat, shuffle, sync
with Manager():
# Create leaf states
A = State(num_values=2, name='A')
B = State(num_values=3, name='B')
# Combine with product (Cartesian product)
C = product([A, B]) # 6 values total
# Iterate and see parent values update
for value in C:
print(f"C={value}, A={A.value}, B={B.value}")
Output:
C=0, A=0, B=0
C=1, A=1, B=0
C=2, A=0, B=1
C=3, A=1, B=1
C=4, A=0, B=2
C=5, A=1, B=2
State Operations
Product (Cartesian Product)
with Manager():
A = State(num_values=2, name='A')
B = State(num_values=3, name='B')
C = product([A, B]) # 6 values (2 × 3)
Stack
with Manager():
A = State(num_values=2, name='A')
B = State(num_values=3, name='B')
C = stack([A, B]) # 5 values (2 + 3)
for _ in C:
# Only one of A or B is active (non-None) at a time
print(f"A={A.value}, B={B.value}")
Slicing
with Manager():
A = State(num_values=10, name='A')
B = A[2:5] # Values 2, 3, 4
C = A[::2] # Even values: 0, 2, 4, 6, 8
D = A[::-1] # Reversed: 9, 8, 7, ..., 0
Repeat
with Manager():
A = State(num_values=3, name='A')
B = repeat(A, 4) # Repeat A four times (12 values)
Shuffle
with Manager():
A = State(num_values=5, name='A')
B = shuffle(A, seed=42) # Randomly permuted order
Synchronize
with Manager():
A = State(num_values=4, name='A')
B = State(num_values=4, name='B')
sync(A, B) # A and B always have same value
Value Propagation
StateTracker uses unidirectional value propagation. When you set a child state's value, all parent states automatically update:
with Manager():
A = State(num_values=2, name='A')
B = State(num_values=3, name='B')
C = product([A, B])
C.value = 5 # Set child value
print(A.value) # 1 (automatically updated)
print(B.value) # 2 (automatically updated)
Visualization
Visualize state dependencies with ASCII trees:
with Manager():
A = State(num_values=2, name='A')
B = State(num_values=3, name='B')
C = product([A, B])
C.name = 'C'
C.print_dag(style='minimal')
Output:
C (n=6)
└── [Product]
├── A (n=2)
└── B (n=3)
Documentation
Full documentation is available at statetracker.readthedocs.io.
License
MIT License - see LICENSE for details.
Metadata
Release files for statetracker 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| statetracker-0.1.1.tar.gz | 25.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| statetracker-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 49.6 kB
Release files / statetracker-0.1.1.tar.gz
| Download URL | statetracker-0.1.1.tar.gz |
|---|---|
| Size | 25.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
16f2fdec94e3fb8582a703e469787c6a4bd4bf6d3a3bb09faf6cf89c1ae109e7
|
|
BLAKE2b-256 checksum How to use checksums |
655d948ac33090c8da8c13e0acbe4533f2f8d96adc8dc2e4dc0c863f33736abe
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / statetracker-0.1.1-py3-none-any.whl
| Download URL | statetracker-0.1.1-py3-none-any.whl |
|---|---|
| Size | 24.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b55019f1476850a2841d886f302357c11adf60e5eeca9686b7ba5548d37190ac
|
|
BLAKE2b-256 checksum How to use checksums |
adc7dc7875e50ed81c87de6b28932fa2392e92e741b9a244634662a78215020c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|