Skip to content

Quick Start

This page shows one small example from each module. Each snippet is self-contained and runnable.

Staffing a queue (Erlang C)

How many agents handle 100 calls in a 30-minute interval, with a 3-minute average handle time, answering 80% of calls within 20 seconds?

python
from pyworkforce.queuing import ErlangC

erlang = ErlangC(transactions=100, asa=20 / 60, aht=3, interval=30, shrinkage=0.3)

requirements = erlang.required_positions(service_level=0.8, max_occupancy=0.85)
print(requirements)
text
{'raw_positions': 14,
 'positions': 20,
 'service_level': 0.8883500191794669,
 'occupancy': 0.7142857142857143,
 'waiting_probability': 0.1741319335950498}

raw_positions are the productive agents needed; positions adds the shrinkage allowance (breaks, training, etc.).

Modeling abandonment (Erlang A)

Real customers hang up. With an average patience of 5 minutes, fewer agents are needed because some callers leave the queue:

python
from pyworkforce.queuing import ErlangA

erlang = ErlangA(transactions=100, aht=3, asa=20 / 60,
                 interval=30, patience=5, shrinkage=0.3)

print(erlang.required_positions(service_level=0.8,
                                max_occupancy=0.85,
                                max_abandonment=0.05))
text
{'raw_positions': 13,
 'positions': 19,
 'service_level': 0.858...,
 'occupancy': 0.750...,
 'abandonment_probability': 0.025...,
 'waiting_probability': 0.226...,
 'average_speed_of_answer': 0.125...}

Building shift coverage

Describe shifts by their clock hours instead of writing 0/1 arrays:

python
from pyworkforce.shifts import shift_coverage_from_hours

shifts_coverage = shift_coverage_from_hours({
    "Morning":   (6, 14),
    "Afternoon": (14, 22),
    "Night":     (22, 6),   # overnight, wraps past midnight
}, num_periods=24)

Scheduling people onto shifts

python
from pyworkforce.scheduling import MinRequiredResources

# Required resources per hour, one row per day.
required_resources = [
    [3, 3, 3, 3, 3, 3, 6, 6, 6, 6, 8, 8, 8, 8, 6, 6, 6, 6, 4, 4, 4, 4, 3, 3],
    [4, 4, 4, 4, 4, 4, 7, 7, 7, 7, 9, 9, 9, 9, 7, 7, 7, 7, 5, 5, 5, 5, 4, 4],
]

scheduler = MinRequiredResources(
    num_days=2,
    periods=24,
    shifts_coverage=shifts_coverage,
    required_resources=required_resources,
    max_period_concurrency=30,
    max_shift_concurrency=30,
)

solution = scheduler.solve()
print(solution["status"], solution["cost"])

Rostering named people

python
from pyworkforce.rostering import MinHoursRoster

roster = MinHoursRoster(
    num_days=2,
    resources=["a@co", "b@co", "c@co"],
    shifts=["Morning", "Night"],
    shifts_hours=[8, 8],
    min_working_hours=8,
    banned_shifts=[{"resource": "a@co", "shift": "Night", "day": 0}],
    max_resting=1,
    required_resources={"Morning": [1, 1], "Night": [1, 1]},
)

solution = roster.solve()
print(solution["status"])

Next, read the Erlang C guide for the theory and a deeper walkthrough.

Released under the MIT License.