# Additional examples

The following examples are included in the SimPy source distribution.

## Car

    from SimPy.Simulation import Process, activate, hold, initialize, now, simulate

    class Car(Process):
        def __init__(self, name, cc):
            Process.__init__(self, name=name)
            self.cc = cc

        def go(self):
            print('%s %s %s' % (now(), self.name, 'Starting'))
            yield hold, self, 100.0
            print('%s %s %s' % (now(), self.name, 'Arrived'))

    initialize()
    c1 = Car('Car1', 2000)                # a new car
    activate(c1, c1.go(), at=6.0)    # activate at time 6.0
    c2 = Car('Car2', 1600)                # another new car
    activate(c2, c2.go())                # activate at time 0
    simulate(until=200)
    print('Current time is %s' % now())    # will print 106.0

Output:

    0 Car2 Starting
    6.0 Car1 Starting
    100.0 Car2 Arrived
    106.0 Car1 Arrived
    Current time is 106.0

## CarT

    from SimPy.SimulationTrace import (Process, activate, initialize, hold, now,
            simulate)

    class Car(Process):
        def __init__(self, name, cc):
            Process.__init__(self, name=name)
            self.cc = cc

        def go(self):
            print('%s %s %s' % (now(), self.name, 'Starting'))
            yield hold, self, 100.0
            print('%s %s %s' % (now(), self.name, 'Arrived'))

    initialize()
    c1 = Car('Car1', 2000)                # a new car
    activate(c1, c1.go(), at=6.0)    # activate at time 6.0
    c2 = Car('Car2', 1600)                # another new car
    activate(c2, c2.go())                # activate at time 0
    simulate(until=200)
    print('Current time is %s' % now())    # will print 106.0

Output:

    0 activate <Car1> at time: 6.0 prior: False
    0 activate <Car2> at time: 0 prior: False
    0 Car2 Starting
    0 hold <Car2> delay: 100.0
    6.0 Car1 Starting
    6.0 hold <Car1> delay: 100.0
    100.0 Car2 Arrived
    100.0 <Car2> terminated
    106.0 Car1 Arrived
    106.0 <Car1> terminated
    Current time is 106.0

## Cars

    from SimPy.Simulation import (Process, Resource, activate, initialize, hold,
            now, release, request, simulate)

    class Car(Process):
        def __init__(self, name, cc):
            Process.__init__(self, name=name)
            self.cc = cc

        def go(self):
            print('%s %s %s' % (now(), self.name, 'Starting'))
            yield request, self, gasstation
            print('%s %s %s' % (now(), self.name, 'Got a pump'))
            yield hold, self, 100.0
            yield release, self, gasstation
            print('%s %s %s' % (now(), self.name, 'Leaving'))

    gasstation = Resource(capacity=2, name='gasStation', unitName='pump')
    initialize()
    c1 = Car('Car1', 2000)
    c2 = Car('Car2', 1600)
    c3 = Car('Car3', 3000)
    c4 = Car('Car4', 1600)
    activate(c1, c1.go(), at=4.0)  # activate at time 4.0
    activate(c2, c2.go())          # activate at time 0.0
    activate(c3, c3.go(), at=3.0)  # activate at time 3.0
    activate(c4, c4.go(), at=3.0)  # activate at time 2.0
    simulate(until=300)
    print('Current time is %s' % now())

Output:

    0 Car2 Starting
    0 Car2 Got a pump
    3.0 Car3 Starting
    3.0 Car3 Got a pump
    3.0 Car4 Starting
    4.0 Car1 Starting
    100.0 Car2 Leaving
    100.0 Car4 Got a pump
    103.0 Car3 Leaving
    103.0 Car1 Got a pump
    200.0 Car4 Leaving
    203.0 Car1 Leaving
    Current time is 203.0

## CarsT

    from SimPy.SimulationTrace import (Process, Resource, activate, initialize,
            hold, now, release, request, simulate)

    class Car(Process):
        def __init__(self, name, cc):
            Process.__init__(self, name=name)
            self.cc = cc

        def go(self):
            print('%s %s %s' % (now(), self.name, 'Starting'))
            yield request, self, gasstation
            print('%s %s %s' % (now(), self.name, 'Got a pump'))
            yield hold, self, 100.0
            yield release, self, gasstation
            print('%s %s %s' % (now(), self.name, 'Leaving'))

    gasstation = Resource(capacity=2, name='gasStation', unitName='pump')
    initialize()
    c1 = Car('Car1', 2000)
    c2 = Car('Car2', 1600)
    c3 = Car('Car3', 3000)
    c4 = Car('Car4', 1600)
    activate(c1, c1.go(), at=4.0)  # activate at time 4.0
    activate(c2, c2.go())          # activate at time 0.0
    activate(c3, c3.go(), at=3.0)  # activate at time 3.0
    activate(c4, c4.go(), at=3.0)  # activate at time 2.0
    simulate(until=300)
    print('Current time is %s' % now())

Output:

    0 activate <Car1> at time: 4.0 prior: False
    0 activate <Car2> at time: 0 prior: False
    0 activate <Car3> at time: 3.0 prior: False
    0 activate <Car4> at time: 3.0 prior: False
    0 Car2 Starting
    0 request <Car2> <gasStation> priority: default
    . . .waitQ: []
    . . .activeQ: ['Car2']
    0 Car2 Got a pump
    0 hold <Car2> delay: 100.0
    3.0 Car3 Starting
    3.0 request <Car3> <gasStation> priority: default
    . . .waitQ: []
    . . .activeQ: ['Car2', 'Car3']
    3.0 Car3 Got a pump
    3.0 hold <Car3> delay: 100.0
    3.0 Car4 Starting
    3.0 request <Car4> <gasStation> priority: default
    . . .waitQ: ['Car4']
    . . .activeQ: ['Car2', 'Car3']
    4.0 Car1 Starting
    4.0 request <Car1> <gasStation> priority: default
    . . .waitQ: ['Car4', 'Car1']
    . . .activeQ: ['Car2', 'Car3']
    100.0 reactivate <Car4> time: 100.0 prior: 1
    100.0 release <Car2> <gasStation>
    . . .waitQ: ['Car1']
    . . .activeQ: ['Car3', 'Car4']
    100.0 Car2 Leaving
    100.0 <Car2> terminated
    100.0 Car4 Got a pump
    100.0 hold <Car4> delay: 100.0
    103.0 reactivate <Car1> time: 103.0 prior: 1
    103.0 release <Car3> <gasStation>
    . . .waitQ: []
    . . .activeQ: ['Car4', 'Car1']
    103.0 Car3 Leaving
    103.0 <Car3> terminated
    103.0 Car1 Got a pump
    103.0 hold <Car1> delay: 100.0
    200.0 release <Car4> <gasStation>
    . . .waitQ: []
    . . .activeQ: ['Car1']
    200.0 Car4 Leaving
    200.0 <Car4> terminated
    203.0 release <Car1> <gasStation>
    . . .waitQ: []
    . . .activeQ: []
    203.0 Car1 Leaving
    203.0 <Car1> terminated
    Current time is 203.0

## Carwash

    from SimPy.Simulation import (Process, SimEvent, Store, activate, get,
            initialize, hold, now, put, simulate, waitevent)
    """Carwash is master"""

    class Carwash(Process):
        """Carwash is master"""
        def __init__(self, name):
            Process.__init__(self, name=name)

        def lifecycle(self):
            while True:
                yield get, self, waitingCars, 1
                carBeingWashed = self.got[0]
                yield hold, self, washtime
                carBeingWashed.doneSignal.signal(self.name)

    class Car(Process):
        """Car is slave"""
        def __init__(self, name):
            Process.__init__(self, name=name)
            self.doneSignal = SimEvent()

        def lifecycle(self):
            yield put, self, waitingCars, [self]
            yield waitevent, self, self.doneSignal
            whichWash = self.doneSignal.signalparam
            print('%s car %s done by %s' % (now(), self.name, whichWash))

    class CarGenerator(Process):
        def generate(self):
            i = 0
            while True:
                yield hold, self, 2
                c = Car('%d' % i)
                activate(c, c.lifecycle())
                i += 1

    washtime = 5
    initialize()

    # put four cars into the queue of waiting cars
    for j in range(1, 5):
            c = Car(name='%d' % -j)
            activate(c, c.lifecycle())

    waitingCars = Store(capacity=40)
    for i in range(2):
            cw = Carwash('Carwash %s' % i)
            activate(cw, cw.lifecycle())

    cg = CarGenerator()
    activate(cg, cg.generate())
    simulate(until=30)
    print('waitingCars %s' % [x.name for x in waitingCars.theBuffer])

Output:

    5 car -1 done by Carwash 0
    5 car -2 done by Carwash 1
    10 car -3 done by Carwash 0
    10 car -4 done by Carwash 1
    15 car 0 done by Carwash 0
    15 car 1 done by Carwash 1
    20 car 2 done by Carwash 0
    20 car 3 done by Carwash 1
    25 car 4 done by Carwash 0
    25 car 5 done by Carwash 1
    30 car 6 done by Carwash 0
    30 car 7 done by Carwash 1
    waitingCars ['10', '11', '12', '13', '14']

## Breakdown

    from SimPy.Simulation import (Process, activate, hold, initialize, now,
            reactivate, simulate)

    class Bus(Process):

        def operate(self, repairduration, triplength):  # PEM
            tripleft = triplength                   # time needed to finish trip
            while tripleft > 0:
                yield hold, self, tripleft         # try to finish the trip
                if self.interrupted():             # if another breakdown occurs
                    print('%s at %s' % (self.interruptCause.name, now()))
                    tripleft = self.interruptLeft   # time to finish the trip
                    self.interruptReset()           # end interrupt state
                    reactivate(br, delay=repairduration)  # restart breakdown br
                    yield hold, self, repairduration      # delay for repairs
                    print('Bus repaired at %s' % now())
                else:
                    break  # no more breakdowns, bus finished trip
            print('Bus has arrived at %s' % now())

    class Breakdown(Process):
        def __init__(self, myBus):
            Process.__init__(self, name='Breakdown ' + myBus.name)
            self.bus = myBus

        def breakBus(self, interval):       # process execution method
            while True:
                yield hold, self, interval  # breakdown interarrivals
                if self.bus.terminated():
                    break
                self.interrupt(self.bus)    # breakdown to myBus

    initialize()
    b = Bus('Bus')      # create a bus object
    activate(b, b.operate(repairduration=20, triplength=1000))
    br = Breakdown(b)   # create breakdown br to bus b
    activate(br, br.breakBus(300))
    simulate(until=4000)
    print('SimPy: No more events at time %s' % now())

Output:

    Breakdown Bus at 300
    Bus repaired at 320
    Breakdown Bus at 620
    Bus repaired at 640
    Breakdown Bus at 940
    Bus repaired at 960
    Bus has arrived at 1060
    SimPy: No more events at time 1260

## Firework

    from SimPy.Simulation import Process, activate, initialize, hold, now, simulate

    class Firework(Process):

        def execute(self):
            print('%s firework launched' % now())
            yield hold, self, 10.0  # wait 10.0 time units
            for i in range(10):
                yield hold, self, 1.0
                print('%s tick' % now())
            yield hold, self, 10.0  # wait another 10.0 time units
            print('%s Boom!!' % now())

    initialize()
    f = Firework()  # create a Firework object, and
                    # activate it (with some default parameters)
    activate(f, f.execute(), at=0.0)
    simulate(until=100)

Output:

    0 firework launched
    11.0 tick
    12.0 tick
    13.0 tick
    14.0 tick
    15.0 tick
    16.0 tick
    17.0 tick
    18.0 tick
    19.0 tick
    20.0 tick
    30.0 Boom!!

## Levelinventory

    from random import normalvariate, seed
    from SimPy.Simulation import (Level, Process, activate, get, initialize, hold,
            now, put, simulate)

    class Deliver(Process):
        def deliver(self):  # an "offeror" PEM
            while True:
                lead = 10.0      # time between refills
                delivery = 10.0  # amount in each refill
                yield put, self, stock, delivery
                print('at %6.4f, add %6.4f units, now amount = %6.4f' %
                        (now(), delivery, stock.amount))
                yield hold, self, lead

    class Demand(Process):
        stockout = 0.0     # initialize initial stockout amount

        def demand(self):  # a "requester" PEM
            day = 1.0      # set time-step to one day
            while True:
                yield hold, self, day
                dd = normalvariate(1.20, 0.20)  # today's random demand
                ds = dd - stock.amount
                # excess of demand over current stock amount
                if dd > stock.amount:     # can't supply requested amount
                    yield get, self, stock, stock.amount
                    # supply all available amount
                    self.stockout += ds
                    # add unsupplied demand to self.stockout
                    print('day %6.4f, demand = %6.4f, shortfall = %6.4f' %
                            (now(), dd, -ds))
                else:  # can supply requested amount
                    yield get, self, stock, dd
                    print('day %6.4f, supplied %6.4f, now amount = %6.4f' %
                            (now(), dd, stock.amount))

    stock = Level(monitored=True)    # 'unbounded' capacity and other defaults

    seed(99999)
    initialize()

    offeror = Deliver()
    activate(offeror, offeror.deliver())
    requester = Demand()
    activate(requester, requester.demand())

    simulate(until=49.9)

    result = (stock.bufferMon.mean(), requester.stockout)
    print('')
    print('Summary of results through end of day %6.4f:' % int(now()))
    print('average stock = %6.4f, cumulative stockout = %6.4f' % result)

Output:

    at 0.0000, add 10.0000 units, now amount = 10.0000
    day 1.0000, supplied 1.0115, now amount = 8.9885
    day 2.0000, supplied 1.1377, now amount = 7.8508
    day 3.0000, supplied 0.7743, now amount = 7.0766
    day 4.0000, supplied 1.4056, now amount = 5.6709
    day 5.0000, supplied 0.9736, now amount = 4.6973
    day 6.0000, supplied 1.1061, now amount = 3.5912
    day 7.0000, supplied 1.4067, now amount = 2.1845
    day 8.0000, supplied 1.2884, now amount = 0.8961
    day 9.0000, demand = 1.4426, shortfall = -0.5465
    at 10.0000, add 10.0000 units, now amount = 10.0000
    day 10.0000, supplied 1.5850, now amount = 8.4150
    day 11.0000, supplied 0.7974, now amount = 7.6176
    day 12.0000, supplied 0.8854, now amount = 6.7323
    day 13.0000, supplied 1.4893, now amount = 5.2430
    day 14.0000, supplied 1.0522, now amount = 4.1908
    day 15.0000, supplied 1.0492, now amount = 3.1416
    day 16.0000, supplied 1.2013, now amount = 1.9403
    day 17.0000, supplied 1.4026, now amount = 0.5377
    day 18.0000, demand = 1.0874, shortfall = -0.5497
    day 19.0000, demand = 1.3043, shortfall = -1.3043
    at 20.0000, add 10.0000 units, now amount = 10.0000
    day 20.0000, supplied 1.2737, now amount = 8.7263
    day 21.0000, supplied 0.9550, now amount = 7.7713
    day 22.0000, supplied 1.3646, now amount = 6.4067
    day 23.0000, supplied 0.8629, now amount = 5.5438
    day 24.0000, supplied 1.2893, now amount = 4.2545
    day 25.0000, supplied 1.1897, now amount = 3.0648
    day 26.0000, supplied 0.9708, now amount = 2.0940
    day 27.0000, supplied 1.1397, now amount = 0.9543
    day 28.0000, demand = 1.1286, shortfall = -0.1743
    day 29.0000, demand = 0.8891, shortfall = -0.8891
    at 30.0000, add 10.0000 units, now amount = 10.0000
    day 30.0000, supplied 0.9496, now amount = 9.0504
    day 31.0000, supplied 1.1515, now amount = 7.8988
    day 32.0000, supplied 1.3724, now amount = 6.5264
    day 33.0000, supplied 0.6977, now amount = 5.8287
    day 34.0000, supplied 1.2291, now amount = 4.5996
    day 35.0000, supplied 1.3502, now amount = 3.2494
    day 36.0000, supplied 1.0396, now amount = 2.2098
    day 37.0000, supplied 1.3442, now amount = 0.8656
    day 38.0000, demand = 1.0919, shortfall = -0.2263
    day 39.0000, demand = 1.4077, shortfall = -1.4077
    at 40.0000, add 10.0000 units, now amount = 10.0000
    day 40.0000, supplied 0.9053, now amount = 9.0947
    day 41.0000, supplied 1.2982, now amount = 7.7965
    day 42.0000, supplied 1.3458, now amount = 6.4508
    day 43.0000, supplied 1.2357, now amount = 5.2151
    day 44.0000, supplied 1.2822, now amount = 3.9329
    day 45.0000, supplied 1.1809, now amount = 2.7519
    day 46.0000, supplied 1.0891, now amount = 1.6629
    day 47.0000, supplied 1.1926, now amount = 0.4702
    day 48.0000, demand = 1.3927, shortfall = -0.9224
    day 49.0000, demand = 1.2690, shortfall = -1.2690

    Summary of results through end of day 49.0000:
    average stock = 4.4581, cumulative stockout = 7.2894

## Message

    from SimPy.Simulation import Process, activate, initialize, hold, now, simulate

    class Message(Process):
        """A simple Process"""
        def __init__(self, i, len):
            Process.__init__(self, name='Message' + str(i))
            self.i = i
            self.len = len

        def go(self):
            print('%s %s %s' % (now(), self.i, 'Starting'))
            yield hold, self, 100.0
            print('%s %s %s' % (now(), self.i, 'Arrived'))

    initialize()
    p1 = Message(1, 203)   # new message
    activate(p1, p1.go())  # activate it
    p2 = Message(2, 33)
    activate(p2, p2.go(), at=6.0)
    simulate(until=200)
    print('Current time is %s' % now())  # will print 106.0

Output:

    0 1 Starting
    6.0 2 Starting
    100.0 1 Arrived
    106.0 2 Arrived
    Current time is 106.0

## Resource

    from SimPy.Simulation import (Process, Resource, activate, initialize, hold,
            now, release, request, simulate)

    class Client(Process):
        inClients = []     # list the clients in order by their requests
        outClients = []    # list the clients in order by completion of service

        def __init__(self, name):
            Process.__init__(self, name)

        def getserved(self, servtime, priority, myServer):
            Client.inClients.append(self.name)
            print('%s requests 1 unit at t = %s' % (self.name, now()))
            # request use of a resource unit
            yield request, self, myServer, priority
            yield hold, self, servtime
            # release the resource
            yield release, self, myServer
            print('%s done at t = %s' % (self.name, now()))
            Client.outClients.append(self.name)

    initialize()

    # the next line creates the ``server`` Resource object
    server = Resource(capacity=2)  # server defaults to qType==FIFO

    # the next lines create some Client process objects
    c1, c2 = Client(name='c1'), Client(name='c2')
    c3, c4 = Client(name='c3'), Client(name='c4')
    c5, c6 = Client(name='c5'), Client(name='c6')

    # in the next lines each client requests
    # one of the ``server``'s Resource units
    activate(c1, c1.getserved(servtime=100, priority=1, myServer=server))
    activate(c2, c2.getserved(servtime=100, priority=2, myServer=server))
    activate(c3, c3.getserved(servtime=100, priority=3, myServer=server))
    activate(c4, c4.getserved(servtime=100, priority=4, myServer=server))
    activate(c5, c5.getserved(servtime=100, priority=5, myServer=server))
    activate(c6, c6.getserved(servtime=100, priority=6, myServer=server))

    simulate(until=500)

    print('Request order: %s' % Client.inClients)
    print('Service order: %s' % Client.outClients)

Output:

    c1 requests 1 unit at t = 0
    c2 requests 1 unit at t = 0
    c3 requests 1 unit at t = 0
    c4 requests 1 unit at t = 0
    c5 requests 1 unit at t = 0
    c6 requests 1 unit at t = 0
    c1 done at t = 100
    c2 done at t = 100
    c3 done at t = 200
    c4 done at t = 200
    c5 done at t = 300
    c6 done at t = 300
    Request order: ['c1', 'c2', 'c3', 'c4', 'c5', 'c6']
    Service order: ['c1', 'c2', 'c3', 'c4', 'c5', 'c6']

## Resource monitor

    from math import sqrt
    from SimPy.Simulation import (Monitor, Process, Resource, activate, initialize,
            hold, now, release, request, simulate)

    class Client(Process):
            inClients = []
            outClients = []

            def __init__(self, name):
                Process.__init__(self, name)

            def getserved(self, servtime, myServer):
                print('%s requests 1 unit at t = %s' % (self.name, now()))
                yield request, self, myServer
                yield hold, self, servtime
                yield release, self, myServer
                print('%s done at t = %s' % (self.name, now()))

    initialize()

    server = Resource(capacity=1, monitored=True, monitorType=Monitor)

    c1, c2 = Client(name='c1'), Client(name='c2')
    c3, c4 = Client(name='c3'), Client(name='c4')

    activate(c1, c1.getserved(servtime=100, myServer=server))
    activate(c2, c2.getserved(servtime=100, myServer=server))
    activate(c3, c3.getserved(servtime=100, myServer=server))
    activate(c4, c4.getserved(servtime=100, myServer=server))

    simulate(until=500)

    print('')
    print('(TimeAverage no. waiting: %s' % server.waitMon.timeAverage())
    print('(Number) Average no. waiting: %.4f' % server.waitMon.mean())
    print('(Number) Var of no. waiting: %.4f' % server.waitMon.var())
    print('(Number) SD of no. waiting: %.4f' % sqrt(server.waitMon.var()))
    print('(TimeAverage no. in service: %s' % server.actMon.timeAverage())
    print('(Number) Average no. in service: %.4f' % server.actMon.mean())
    print('(Number) Var of no. in service: %.4f' % server.actMon.var())
    print('(Number) SD of no. in service: %.4f' % sqrt(server.actMon.var()))
    print('=' * 40)
    print('Time history for the "server" waitQ:')
    print('[time, waitQ]')
    for item in server.waitMon:
            print(item)
    print('=' * 40)
    print('Time history for the "server" activeQ:')
    print('[time, activeQ]')
    for item in server.actMon:
            print(item)

Output:

    c1 requests 1 unit at t = 0
    c2 requests 1 unit at t = 0
    c3 requests 1 unit at t = 0
    c4 requests 1 unit at t = 0
    c1 done at t = 100
    c2 done at t = 200
    c3 done at t = 300
    c4 done at t = 400

    (TimeAverage no. waiting: 1.5
    (Number) Average no. waiting: 1.2857
    (Number) Var of no. waiting: 1.0612
    (Number) SD of no. waiting: 1.0302
    (TimeAverage no. in service: 1.0
    (Number) Average no. in service: 0.4444
    (Number) Var of no. in service: 0.2469
    (Number) SD of no. in service: 0.4969
    ========================================
    Time history for the "server" waitQ:
    [time, waitQ]
    [0, 0]
    [0, 1]
    [0, 2]
    [0, 3]
    [100, 2]
    [200, 1]
    [300, 0]
    ========================================
    Time history for the "server" activeQ:
    [time, activeQ]
    [0, 0]
    [0, 1]
    [100, 0]
    [100, 1]
    [200, 0]
    [200, 1]
    [300, 0]
    [300, 1]
    [400, 0]

## Shopping

    from SimPy.Simulation import Process, activate, hold, initialize, simulate

    class Customer(Process):
        def buy(self,   budget=0):
            print('Here I am at the shops %s' % self.name)
            t = 5.0
            for i in range(4):
                yield hold, self, t
                # executed 4 times at intervals of t time units
                print('I just bought something %s' % self.name)
                budget -= 10.00
            print('All I have left is %s I am going home %s' % (budget, self.name))

    initialize()

    # create a customer named "Evelyn",
    C = Customer(name='Evelyn')

    # and activate her with a budget of 100
    activate(C, C.buy(budget=100), at=10.0)

    simulate(until=100.0)

Output:

    Here I am at the shops Evelyn
    I just bought something Evelyn
    I just bought something Evelyn
    I just bought something Evelyn
    I just bought something Evelyn
    All I have left is 60.0 I am going home Evelyn

## Storewidget

    from SimPy.Simulation import (Lister, Process, Store, activate, get, hold,
        initialize, now, put, simulate)

    class ProducerD(Process):
        def __init__(self):
            Process.__init__(self)

        def produce(self):  # the ProducerD PEM
            while True:
                yield put, self, buf, [Widget(9), Widget(7)]
                yield hold, self, 10

    class ConsumerD(Process):
        def __init__(self):
            Process.__init__(self)

        def consume(self):  # the ConsumerD PEM
            while True:
                toGet = 3
                yield get, self, buf, toGet
                assert len(self.got) == toGet
                print('%s Get widget weights %s' % (now(),
                        [x.weight for x in self.got]))
                yield hold, self, 11

    class Widget(Lister):
        def __init__(self, weight=0):
            self.weight = weight

    widgbuf = []
    for i in range(10):
        widgbuf.append(Widget(5))

    initialize()

    buf = Store(capacity=11, initialBuffered=widgbuf, monitored=True)

    for i in range(3):  # define and activate 3 producer objects
        p = ProducerD()
        activate(p, p.produce())

    for i in range(3):  # define and activate 3 consumer objects
        c = ConsumerD()
        activate(c, c.consume())

    simulate(until=50)

    print('LenBuffer: %s' % buf.bufferMon)  # length of buffer
    print('getQ: %s' % buf.getQMon)         # length of getQ
    print('putQ %s' % buf.putQMon)          # length of putQ

Output:

    0 Get widget weights [5, 5, 5]
    0 Get widget weights [5, 5, 5]
    0 Get widget weights [5, 5, 5]
    11 Get widget weights [5, 9, 7]
    11 Get widget weights [9, 7, 9]
    11 Get widget weights [7, 9, 7]
    22 Get widget weights [9, 7, 9]
    22 Get widget weights [7, 9, 7]
    22 Get widget weights [9, 7, 9]
    33 Get widget weights [7, 9, 7]
    33 Get widget weights [9, 7, 9]
    40 Get widget weights [7, 9, 7]
    44 Get widget weights [9, 7, 9]
    50 Get widget weights [7, 9, 7]
    LenBuffer: [[0, 10], [0, 7], [0, 9], [0, 11], [0, 8], [0, 10], [0, 7], [10, 9], [10, 11], [11, 8], [11, 10], [11, 7], [11, 4], [20, 6], [20, 8], [21, 10], [22, 7], [22, 4], [22, 1], [30, 3], [30, 5], [31, 7], [33, 4], [33, 1], [40, 3], [40, 0], [40, 2], [41, 4], [44, 1], [50, 3], [50, 0], [50, 2]]
    getQ: [[0, 0], [33, 1], [40, 0], [44, 1], [50, 0]]
    putQ [[0, 0], [0, 1], [0, 2], [0, 3], [0, 2], [0, 1], [0, 0], [10, 1], [11, 0]]