Skip to main content

A Polars plugin for easily scheduling recurring events with constraints.

Project description

Polars Scheduler

downloads uv pdm-managed PyPI Supported Python versions License pre-commit.ci status

A Polars plugin for easily scheduling recurring events with constraints.

Installation

pip install polars-scheduler[polars]

On older CPUs run:

pip install polars-scheduler[polars-lts-cpu]

Features

  • Powerful Constraint System: Schedule events with constraints like "≥6h apart", "≥1h before food", or "≥2h after medicine"
  • Time Windows: Define preferred time windows for events (e.g., breakfast at "08:00", or dinner between "18:00-20:00")
  • Optimization Strategies: Choose between "earliest" (soonest possible scheduling) or "latest" (just-in-time)
  • Smart Distribution: Automatically distributes multiple daily instances across different time windows
  • Mixed Integer Linear Programming: Uses MILP solver to find optimal schedules that satisfy all constraints

Usage

The plugin adds a scheduler namespace to Polars DataFrames with methods for registering events and constraints.

Here is a full demo showing how to:

  • create a schedule
  • add events with constraints
  • generate both an "earliest" and a "latest" schedule
import polars as pl
import polars_scheduler  # noqa: F401

# Create a new empty schedule
schedule = pl.DataFrame().scheduler.new()

# Add simple meal and medication schedule
schedule = schedule.scheduler.add(
    event="breakfast",
    category="meal",
    unit="serving",
    frequency="1x daily",
    windows=["08:00"],
)

schedule = schedule.scheduler.add(
    event="lunch",
    category="meal",
    unit="serving",
    frequency="1x daily",
    windows=["12:00-13:00"],
)

schedule = schedule.scheduler.add(
    event="dinner",
    category="meal",
    unit="serving",
    frequency="1x daily",
    windows=["18:00-20:00"],
)

schedule = schedule.scheduler.add(
    event="vitamin",
    category="supplement",
    unit="pill",
    frequency="1x daily",
    constraints=["≥1h after meal"],
)

schedule = schedule.scheduler.add(
    event="antibiotic",
    category="medication",
    unit="pill",
    frequency="2x daily",
    constraints=["≥6h apart", "≥1h before food"],
)

schedule = schedule.scheduler.add(
    event="probiotic",
    category="supplement",
    unit="capsule",
    frequency="1x daily",
    constraints=["≥2h after antibiotic"],
)

schedule = schedule.scheduler.add(
    event="protein shake",
    category="supplement",
    unit="gram",
    amount=30,
    frequency="1x daily",
    constraints=[],
    windows=["08:00", "17:00-19:00"],
    note="mix with 300ml water",
)

schedule = schedule.scheduler.add(
    event="ginger",
    category="supplement",
    unit="shot",
    frequency="1x daily",
    constraints=["≥1h before breakfast"],
)

schedule = schedule.scheduler.add(
    event="gym",
    category="exercise",
    unit="session",
    frequency="3x weekly",
)

# Print the original schedule
print("--- Schedule Constraints ---")
print(schedule)

# Generate an optimized schedule (Earliest)
result = schedule.scheduler.schedule(
    strategy="earliest",
    day_start="07:00",
    day_end="22:00",
)

print("\n--- Optimized Schedule (Earliest) ---")
print(result.select(["entity_name", "instance", "time_hhmm", "Category"]))

# Generate an optimized schedule (Latest)
result_latest = schedule.scheduler.schedule(
    strategy="latest",
    day_start="07:00",
    day_end="22:00",
)

print("\n--- Latest Schedule ---")
print(result_latest.select(["entity_name", "instance", "time_hhmm", "Category"]))

Example output:

--- Schedule Constraints ---
shape: (9, 9)
┌────────────┬────────────┬─────────┬────────┬───┬───────────┬────────────┬────────────┬───────────┐
│ Event      ┆ Category   ┆ Unit    ┆ Amount ┆ … ┆ Frequency ┆ Constraint ┆ Windows    ┆ Note      │
│ ---        ┆ ---        ┆ ---     ┆ ---    ┆   ┆ ---       ┆ s          ┆ ---        ┆ ---       │
│ str        ┆ str        ┆ str     ┆ f64    ┆   ┆ str       ┆ list[str]  ┆ list[str]  ┆ str       │
╞════════════╪════════════╪═════════╪════════╪═══╪═══════════╪════════════╪════════════╪═══════════╡
│ breakfast  ┆ meal       ┆ serving ┆ null   ┆ … ┆ 1x daily  ┆ []         ┆ ["08:00"]  ┆ null      │
│ lunch      ┆ meal       ┆ serving ┆ null   ┆ … ┆ 1x daily  ┆ []         ┆ ["12:00-13 │ null      │
│            ┆            ┆         ┆        ┆   ┆           ┆            ┆ :00"]      ┆           │
│ dinner     ┆ meal       ┆ serving ┆ null   ┆ … ┆ 1x daily  ┆ []         ┆ ["18:00-20 │ null      │
│            ┆            ┆         ┆        ┆   ┆           ┆            ┆ :00"]      ┆           │
│ vitamin    ┆ supplement ┆ pill    ┆ null   ┆ … ┆ 1x daily  ┆ ["≥1h      ┆ []         ┆ null      │
│            ┆            ┆         ┆        ┆   ┆           ┆ after      ┆            ┆           │
│            ┆            ┆         ┆        ┆   ┆           ┆ meal"]     ┆            ┆           │
│ antibiotic ┆ medication ┆ pill    ┆ null   ┆ … ┆ 2x daily  ┆ ["≥6h      ┆ []         ┆ null      │
│            ┆            ┆         ┆        ┆   ┆           ┆ apart",    ┆            ┆           │
│            ┆            ┆         ┆        ┆   ┆           ┆ "≥1h       ┆            ┆           │
│            ┆            ┆         ┆        ┆   ┆           ┆ before foo ┆            ┆           │
│ probiotic  ┆ supplement ┆ capsule ┆ null   ┆ … ┆ 1x daily  ┆ ["≥2h      ┆ []         ┆ null      │
│            ┆            ┆         ┆        ┆   ┆           ┆ after anti ┆            ┆           │
│            ┆            ┆         ┆        ┆   ┆           ┆ biotic"]   ┆            ┆           │
│ protein    ┆ supplement ┆ gram    ┆ 30.0   ┆ … ┆ 1x daily  ┆ []         ┆ ["08:00",  ┆ mix with  │
│ shake      ┆            ┆         ┆        ┆   ┆           ┆            ┆ "17:00-19: ┆ 300ml     │
│            ┆            ┆         ┆        ┆   ┆           ┆            ┆ 00"]       ┆ water     │
│ ginger     ┆ supplement ┆ shot    ┆ null   ┆ … ┆ 1x daily  ┆ ["≥1h      ┆ []         ┆ null      │
│            ┆            ┆         ┆        ┆   ┆           ┆ before bre ┆            ┆           │
│            ┆            ┆         ┆        ┆   ┆           ┆ akfast"]   ┆            ┆           │
│ gym        ┆ exercise   ┆ session ┆ null   ┆ … ┆ 3x weekly ┆ []         ┆ []         ┆ null      │
└────────────┴────────────┴─────────┴────────┴───┴───────────┴────────────┴────────────┴───────────┘

--- Optimized Schedule (Earliest) ---
shape: (12, 4)
┌───────────────┬──────────┬───────────┬────────────┐
│ entity_name   ┆ instance ┆ time_hhmm ┆ Category   │
│ ---           ┆ ---      ┆ ---       ┆ ---        │
│ str           ┆ i32      ┆ str       ┆ str        │
╞═══════════════╪══════════╪═══════════╪════════════╡
│ lunch         ┆ 1        ┆ 07:00     ┆ meal       │
│ probiotic     ┆ 1        ┆ 07:00     ┆ supplement │
│ gym           ┆ 2        ┆ 07:00     ┆ exercise   │
│ dinner        ┆ 1        ┆ 07:00     ┆ meal       │
│ antibiotic    ┆ 1        ┆ 07:00     ┆ medication │
│ …             ┆ …        ┆ …         ┆ …          │
│ vitamin       ┆ 1        ┆ 07:00     ┆ supplement │
│ protein shake ┆ 1        ┆ 07:00     ┆ supplement │
│ breakfast     ┆ 1        ┆ 07:00     ┆ meal       │
│ gym           ┆ 3        ┆ 07:00     ┆ exercise   │
│ antibiotic    ┆ 2        ┆ 13:00     ┆ medication │
└───────────────┴──────────┴───────────┴────────────┘

--- Latest Schedule ---
shape: (12, 4)
┌───────────────┬──────────┬───────────┬────────────┐
│ entity_name   ┆ instance ┆ time_hhmm ┆ Category   │
│ ---           ┆ ---      ┆ ---       ┆ ---        │
│ str           ┆ i32      ┆ str       ┆ str        │
╞═══════════════╪══════════╪═══════════╪════════════╡
│ antibiotic    ┆ 1        ┆ 16:00     ┆ medication │
│ lunch         ┆ 1        ┆ 22:00     ┆ meal       │
│ vitamin       ┆ 1        ┆ 22:00     ┆ supplement │
│ protein shake ┆ 1        ┆ 22:00     ┆ supplement │
│ dinner        ┆ 1        ┆ 22:00     ┆ meal       │
│ …             ┆ …        ┆ …         ┆ …          │
│ gym           ┆ 1        ┆ 22:00     ┆ exercise   │
│ breakfast     ┆ 1        ┆ 22:00     ┆ meal       │
│ antibiotic    ┆ 2        ┆ 22:00     ┆ medication │
│ probiotic     ┆ 1        ┆ 22:00     ┆ supplement │
│ ginger        ┆ 1        ┆ 22:00     ┆ supplement │
└───────────────┴──────────┴───────────┴────────────┘

Constraint Types

The scheduler supports several constraint types:

  • Apart constraint: "≥6h apart" - Ensures that multiple instances of the same entity are scheduled at least 6 hours apart
  • Before constraint: "≥1h before food" - Ensures that an entity is scheduled at least 1 hour before any entity in the "food" category
  • After constraint: "≥2h after medication" - Ensures that an entity is scheduled at least 2 hours after any entity in the "medication" category

When both "before" and "after" constraints are specified for the same entity-category pair, they are combined as an "OR" constraint using a big-M formulation, not an "AND" constraint (which would often be impossible to satisfy).

Window Specifications

Windows can be specified in two formats:

  • Anchor: "08:00" - A specific time point
  • Range: "18:00-20:00" - A time range

When multiple instances of the same entity need to be scheduled, the solver will try to distribute them across different windows.

Optimization Strategies

  • Earliest: Places events as early as possible while satisfying all constraints
  • Latest: Places events as late as possible while satisfying all constraints

Standalone CLI Tool

The project also includes a standalone command-line tool for scheduling:

cd scheduler-cli
cargo run -- --strategy earliest --start=07:00 --end=22:00

Development

To build the project:

  1. Build the core library:

    cd scheduler-core
    cargo build
    
  2. Build the CLI tool:

    cd scheduler-cli
    cargo build
    
  3. Build the Python bindings:

    cd polars-scheduler-py
    maturin develop
    

License

MIT License

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

polars_scheduler-0.2.0.tar.gz (54.3 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

polars_scheduler-0.2.0-cp38-abi3-win_amd64.whl (3.5 MB view details)

Uploaded CPython 3.8+Windows x86-64

polars_scheduler-0.2.0-cp38-abi3-win32.whl (3.4 MB view details)

Uploaded CPython 3.8+Windows x86

polars_scheduler-0.2.0-cp38-abi3-manylinux_2_34_ppc64le.whl (4.0 MB view details)

Uploaded CPython 3.8+manylinux: glibc 2.34+ ppc64le

polars_scheduler-0.2.0-cp38-abi3-manylinux_2_28_i686.whl (4.0 MB view details)

Uploaded CPython 3.8+manylinux: glibc 2.28+ i686

polars_scheduler-0.2.0-cp38-abi3-manylinux_2_28_aarch64.whl (3.3 MB view details)

Uploaded CPython 3.8+manylinux: glibc 2.28+ ARM64

polars_scheduler-0.2.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.9 MB view details)

Uploaded CPython 3.8+manylinux: glibc 2.17+ x86-64

polars_scheduler-0.2.0-cp38-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl (6.5 MB view details)

Uploaded CPython 3.8+manylinux: glibc 2.17+ s390x

polars_scheduler-0.2.0-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (3.9 MB view details)

Uploaded CPython 3.8+manylinux: glibc 2.17+ ARMv7l

polars_scheduler-0.2.0-cp38-abi3-macosx_11_0_arm64.whl (3.0 MB view details)

Uploaded CPython 3.8+macOS 11.0+ ARM64

polars_scheduler-0.2.0-cp38-abi3-macosx_10_12_x86_64.whl (3.6 MB view details)

Uploaded CPython 3.8+macOS 10.12+ x86-64

File details

Details for the file polars_scheduler-0.2.0.tar.gz.

File metadata

  • Download URL: polars_scheduler-0.2.0.tar.gz
  • Upload date:
  • Size: 54.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: pdm/2.22.4 CPython/3.11.11 Linux/6.8.0-51-generic

File hashes

Hashes for polars_scheduler-0.2.0.tar.gz
Algorithm Hash digest
SHA256 dcdcd74bab65920e3eda43b26a2026d4f8cbbff66fa86eea37f5e0bc1a4ab0f7
MD5 8b29a8d5261547deaef03be662ae8a09
BLAKE2b-256 e8973b2473aacc943f05a111f83e68a6bd42cce371dce5289b65e7deb21fd63d

See more details on using hashes here.

File details

Details for the file polars_scheduler-0.2.0-cp38-abi3-win_amd64.whl.

File metadata

  • Download URL: polars_scheduler-0.2.0-cp38-abi3-win_amd64.whl
  • Upload date:
  • Size: 3.5 MB
  • Tags: CPython 3.8+, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: pdm/2.22.4 CPython/3.11.11 Linux/6.8.0-51-generic

File hashes

Hashes for polars_scheduler-0.2.0-cp38-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 5b4e45a497c17d160a47da485e45d0a874faaaa9ad4f8b0388da6c81552d67b8
MD5 7ba52eae56db58a8bc1d0b0aa0d3d3fe
BLAKE2b-256 0a9a630d2c4aa55730f6fc1264a8c9f70902382f88f2d57f3eb08d7e73ba8fac

See more details on using hashes here.

File details

Details for the file polars_scheduler-0.2.0-cp38-abi3-win32.whl.

File metadata

  • Download URL: polars_scheduler-0.2.0-cp38-abi3-win32.whl
  • Upload date:
  • Size: 3.4 MB
  • Tags: CPython 3.8+, Windows x86
  • Uploaded using Trusted Publishing? No
  • Uploaded via: pdm/2.22.4 CPython/3.11.11 Linux/6.8.0-51-generic

File hashes

Hashes for polars_scheduler-0.2.0-cp38-abi3-win32.whl
Algorithm Hash digest
SHA256 1af508749aacb90442be4a4bbdfa2cf5da4164337792384cd64bf27ace79d6f9
MD5 af9696034e61151c504db50640c2ec25
BLAKE2b-256 4c9836b9aaf91ed90d3255b96fb781d502c0ba855faadee9f803932f40fe19c6

See more details on using hashes here.

File details

Details for the file polars_scheduler-0.2.0-cp38-abi3-manylinux_2_34_ppc64le.whl.

File metadata

File hashes

Hashes for polars_scheduler-0.2.0-cp38-abi3-manylinux_2_34_ppc64le.whl
Algorithm Hash digest
SHA256 af0e6da8486c591a61b0b9e9fe9089d58f22248fdf7e620cb4e071b30d5fdd1d
MD5 4dfb929a5932c317ed8c73cea6578eab
BLAKE2b-256 f205bc0377312fef08fca7ca3b29b0ef9f63aa9500f5f33636426ae3dab9f090

See more details on using hashes here.

File details

Details for the file polars_scheduler-0.2.0-cp38-abi3-manylinux_2_28_i686.whl.

File metadata

File hashes

Hashes for polars_scheduler-0.2.0-cp38-abi3-manylinux_2_28_i686.whl
Algorithm Hash digest
SHA256 cbc575e68f1ea2cfc8584cae7a31414af264df8adc1198643fc4f5c2b25d7af5
MD5 63a9e4c12646d5a5cfcf6cf1fb2483d8
BLAKE2b-256 7fb4e760ef9601fc6c27eec3c759b48c86179a74e84ef9193ab2aa575aa5d1da

See more details on using hashes here.

File details

Details for the file polars_scheduler-0.2.0-cp38-abi3-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for polars_scheduler-0.2.0-cp38-abi3-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 19bfb5a1d53e18c7abe48de5e36c3bd0db6d10b387ab2d3bb703633dc2bd09d6
MD5 e3a62f7f83a786b2cc9142cb26e8e056
BLAKE2b-256 3608d573b27866900e075621daddb287b0ed14be5bfec58b5849c90d026c2abc

See more details on using hashes here.

File details

Details for the file polars_scheduler-0.2.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for polars_scheduler-0.2.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 6d9d663e62cb252823d6cc7aaa84e1c795b4befacdb58eefe840365ebcfe59c2
MD5 e3119de2a6dc6e4b33ac899568797b9a
BLAKE2b-256 1018d277e33aa376704ca0f0702f78447ea8269e3d4f4d0f5c51530009e42a2d

See more details on using hashes here.

File details

Details for the file polars_scheduler-0.2.0-cp38-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl.

File metadata

File hashes

Hashes for polars_scheduler-0.2.0-cp38-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl
Algorithm Hash digest
SHA256 3f6a1b0994462e7aeafd3898d9e6f7b0bc29b64ba95d21aff91e6691fd4db3b1
MD5 829397bbbbc3b1a864377e1b97eba6ff
BLAKE2b-256 91cea8011a2b988588bc3d1a4f9c753d75d25656440a6beabd0a0c1b96185a4a

See more details on using hashes here.

File details

Details for the file polars_scheduler-0.2.0-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for polars_scheduler-0.2.0-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 313ce46d9b41a24935e64471eda472c38728a5ab49ae1573d7f9d57f3fc96306
MD5 655061e18e70b4a3391a2f83c61d0e88
BLAKE2b-256 601ef698abaddd24d92917cff0c30adf82f3eb681cfc8fea4d64a713e7536b06

See more details on using hashes here.

File details

Details for the file polars_scheduler-0.2.0-cp38-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for polars_scheduler-0.2.0-cp38-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 02abc8ca2c42cfb11a1022490af85810e6065926eafd2ea26605d5faeec14a32
MD5 cc35bba548778f38966d74b31823192a
BLAKE2b-256 d100a5d26ce7df2f54618a5c73ec6285bdba74f486ad411aa1f4b72b4b897c2b

See more details on using hashes here.

File details

Details for the file polars_scheduler-0.2.0-cp38-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for polars_scheduler-0.2.0-cp38-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 fc8e1746d0928c4c25d421c4466b5a3c435a00f5a42dee28f1cb99adbf61bd27
MD5 f73f2321d71953937e4d74a57aa4a1f5
BLAKE2b-256 c03c9c05f568b553905e13b2fa4f443bc782a76caea860be5eb064726fadd7da

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page