Bonnie Douglas | 1 Oct 11:36

Re: Creating multiple Store objects from a list

Bonnie Douglas <bonnie.douglas <at> biarri.com> writes:

> 
> Hi,
> I am new to Python and SimPy.  I have a dictionary of store locations 
> and their capacities.  Rather than hardcoding the creation of store 
> objects in my module I would like to generate them using an iterator.
> I've tried to use the following
> storedic = {['place1':12, 'place2':10, 'place3':15]
> for k, v in storedic.iteritems():
>     sObj = Store(name=k, capacity = v)
> 
> But, the yield put statement in my process generates an error:
> yield put, self, sObj.name = 'place1', 1
> 
> I realise that I have 3 objects with the identifier sObj.  Is there a 
> way to reference the storage object by name in yield put and yield get 
> statements? 
> Regards,
> Bonnie Douglas
> 
> ------------------------------------------------------------------------------
> Come build with us! The BlackBerry® Developer Conference in SF, CA
> is the only developer event you need to attend this year. Jumpstart your

For the record, Klaus kindly replied to my post below with the following, which 
solved my problem brilliantly:

Hi Bonnie,
is this what you are after:
(Continue reading)

Tony Vignaux | 7 Oct 20:31
Picon
Gravatar

A problem with startCollection

There seems to be a problem with startCollection. It is not recognised by Simpy version 2.0 Revision 163 on Ubuntu 9 or Mac OS 10.6.1. It is recognised by SimPy version 1.9.1 $Revision: 1.1.1.78 $ $Date: 2008/03/03 13:49:59 $ on NetBSD machines at the local university.

G A Vignaux

------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay 
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
_______________________________________________
Simpy-users mailing list
Simpy-users <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/simpy-users
Klaus G. Muller | 7 Oct 22:09
Picon
Picon
Favicon

Re: A problem with startCollection

All:
this is a code error in the traditional API of SimPy 2.0.1.

As a workaround, use "Globals.sim.startCollection()" instead of "startCollection()".

Klaus Müller

Tony Vignaux wrote:
There seems to be a problem with startCollection. It is not recognised by Simpy version 2.0 Revision 163 on Ubuntu 9 or Mac OS 10.6.1. It is recognised by SimPy version 1.9.1 $Revision: 1.1.1.78 $ $Date: 2008/03/03 13:49:59 $ on NetBSD machines at the local university.

G A Vignaux
------------------------------------------------------------------------------ Come build with us! The BlackBerry(R) Developer Conference in SF, CA is the only developer event you need to attend this year. Jumpstart your developing skills, take BlackBerry mobile applications to market and stay ahead of the curve. Join us from November 9 - 12, 2009. Register now! http://p.sf.net/sfu/devconference _______________________________________________ Simpy-users mailing list Simpy-users <at> lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/simpy-users

------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay 
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
_______________________________________________
Simpy-users mailing list
Simpy-users <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/simpy-users
Bonnie Douglas | 8 Oct 07:06

Use of filter function on store

Hello again group,
Yet another question on a problem that I'm having that is likely a result of my 
inexperience with Python.

I am trying to pull items (which are processes) out of a store based on specific 
item attributes. I do not understand the explanation of the use of filter 
functions in the in-depth SimPy manual.  I have created a small test program 
(below).  

I do not understand:
1. whether the filter should be defined globally or locally (within the Unit 
process).
2. whether the attributes against which I'm testing must be defined globally or 
locally.

I have tried several different configurations with no success.  

Any help would be greatly appreciated.
Kind Regards,
Bonnie Douglas

test.py
----------------------------------------
import csv
from SimPy.Simulation import *

wT = ""
pS = ""

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

    def run(self):           # the ProducerD PEM
        while True:
            for li in maintfault:
                wT = li[0]
                pS = li[1]
                print 'At', now(), ' I wanted type: ', wT, ' pack: ', pS
                yield get, self, sObj, wagType
                print 'At', now(), ' I wanted type: ', wT, ' pack: ', pS, ' I 
got:', self.got                
                yield put, self, sObj, self.got #put them all back  yield hold, 
self, 1 # wait for 10 units for the heck of it                
                yield put, self, sObj, self.got #put them all back

class Wagon(Process):
    def __init__(self,wType,pkSize):
        Process.__init__(self, wType, pkSize)
        self.moveSignal=SimEvent()
        self.pksize=pkSize
        self.wagType=wType
    def storeme(self):
        yield put,self,sObj,[self]
        yield waitevent,self,self.moveSignal
        yield hold, self, 10

def wagType(buff):
    """  filter: get all wagons with .type = type from store. """
    result=[]
    print 'in wagType function wtype: ', wT, ' ps: ', pS
    if wT == "ALL" and pS == "ALL":
        result = buff
    else:
        if wT == "ALL":
            for i in buff:
                if i.pkSize == pS:
                    result.append(i)
        if pS == "ALL":
            for i in buff:
                if i.wagType == wT:
                    result.append(i)
        else:
            for i in buff:
                if i.wagType == wT and i.pkSize == pS:
                    result.append(i)
    return result

def read_as_dict(filename):
    """
    example
    =======
    toast = {}
    for row in read_as_dict("thing.csv"):
        toast[row["type"]] = Store(name=row["type"], cap=row['cap'], etc)
    """
    return csv.DictReader(open(filename, "rb"))

initialize()
################################################
## read input data in from files
################################################
sObj = Store(name='a_store',
             unitName='wagons',
             capacity=9999,
             monitored=True,
             monitorType=Monitor)

#maintfault=[]
#for row in read_as_dict("MaintenanceFault.csv"):
#    maintfault.append( [row["wagonType"],row["pkSize"], 
row["FaultType"],row["FaultDescr"], row["daysToSM"], 
row["pFaultLowUTM"],row["pFaultHighUTM"], \
#                        row["pFaultLowFX1"], row["pFaultHighFX1"], 
row["repDistribution"],row["repDurMinMode"], \
#                        row["repDurHigh"],row["repDurLow"], 
row["repDurMinAvg"], row["repDurMinStdDev"]] )

maintfault = [["ALL","ALL"],["NHRH","ALL"],["NHRH",4],["TTTT",3]]

w1 = Wagon("NHRH",8)
activate(w1,w1.storeme())
w2 = Wagon("NHPH",7)
activate(w2,w2.storeme())
w3 = Wagon("TTTT",3)
activate(w3,w3.storeme())

u = Unit()
activate(u,u.run()) 

------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay 
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
Klaus G. Muller | 8 Oct 08:30
Picon
Picon
Favicon

Re: Use of filter function on store

Bonnie,
here is an example of how the filter function should be written:

from SimPy.Simulation import *
import random as rand

class Parcel:
    def __init__(self,parcelType):
        self.ptype = parcelType

class ParcelProducer(Process):
    def produce(self,store):
        while True:
            yield hold,self,1
            parcl = Parcel(parcelType = rand.choice(["Light","Heavy"]))
            yield put,self,store,[parcl]

class ParcelConsumer(Process):
    def consume(self,store):
        while True:
            yield get,self,store,heavies
            found = self.got
            print "Time %s: retrieved parcel type is %s"%(now(),[x.ptype 
for x in found])

def heavies(buff):
    """filter function. Only get 'Heavy' parcels"""
    res = []
    for item in buff:
        if item.ptype == "Heavy":
            res.append(item)
    return res

rand.seed(12345)
initialize()
s = Store(capacity = 1000)
pp = ParcelProducer()
activate(pp,pp.produce(store = s))
pc =ParcelConsumer()
activate(pc,pc.consume(store = s))
simulate(until=15)
print "Left in store: parcels of type: %s"%[x.ptype for x in s.theBuffer]

The filter function must have only one parameter (standing for the 
Store's buffer). It must be in the scope of the "yield get" which uses it.

OK?

Klaus Müller

Bonnie Douglas wrote:
> Hello again group,
> Yet another question on a problem that I'm having that is likely a result of my 
> inexperience with Python.
>
> I am trying to pull items (which are processes) out of a store based on specific 
> item attributes. I do not understand the explanation of the use of filter 
> functions in the in-depth SimPy manual.  I have created a small test program 
> (below).  
>
> I do not understand:
> 1. whether the filter should be defined globally or locally (within the Unit 
> process).
> 2. whether the attributes against which I'm testing must be defined globally or 
> locally.
>
> I have tried several different configurations with no success.  
>
> Any help would be greatly appreciated.
> Kind Regards,
> Bonnie Douglas
>
> test.py
> ----------------------------------------
> import csv
> from SimPy.Simulation import *
>
> wT = ""
> pS = ""
>
> class Unit(Process):
>     def __init__(self):
>         Process.__init__(self)
>         
>     def run(self):           # the ProducerD PEM
>         while True:
>             for li in maintfault:
>                 wT = li[0]
>                 pS = li[1]
>                 print 'At', now(), ' I wanted type: ', wT, ' pack: ', pS
>                 yield get, self, sObj, wagType
>                 print 'At', now(), ' I wanted type: ', wT, ' pack: ', pS, ' I 
> got:', self.got                
>                 yield put, self, sObj, self.got #put them all back  yield hold, 
> self, 1 # wait for 10 units for the heck of it                
>                 yield put, self, sObj, self.got #put them all back
>     
> class Wagon(Process):
>     def __init__(self,wType,pkSize):
>         Process.__init__(self, wType, pkSize)
>         self.moveSignal=SimEvent()
>         self.pksize=pkSize
>         self.wagType=wType
>     def storeme(self):
>         yield put,self,sObj,[self]
>         yield waitevent,self,self.moveSignal
>         yield hold, self, 10
>
> def wagType(buff):
>     """  filter: get all wagons with .type = type from store. """
>     result=[]
>     print 'in wagType function wtype: ', wT, ' ps: ', pS
>     if wT == "ALL" and pS == "ALL":
>         result = buff
>     else:
>         if wT == "ALL":
>             for i in buff:
>                 if i.pkSize == pS:
>                     result.append(i)
>         if pS == "ALL":
>             for i in buff:
>                 if i.wagType == wT:
>                     result.append(i)
>         else:
>             for i in buff:
>                 if i.wagType == wT and i.pkSize == pS:
>                     result.append(i)
>     return result
>     
> def read_as_dict(filename):
>     """
>     example
>     =======
>     toast = {}
>     for row in read_as_dict("thing.csv"):
>         toast[row["type"]] = Store(name=row["type"], cap=row['cap'], etc)
>     """
>     return csv.DictReader(open(filename, "rb"))
>
> initialize()
> ################################################
> ## read input data in from files
> ################################################
> sObj = Store(name='a_store',
>              unitName='wagons',
>              capacity=9999,
>              monitored=True,
>              monitorType=Monitor)
>
> #maintfault=[]
> #for row in read_as_dict("MaintenanceFault.csv"):
> #    maintfault.append( [row["wagonType"],row["pkSize"], 
> row["FaultType"],row["FaultDescr"], row["daysToSM"], 
> row["pFaultLowUTM"],row["pFaultHighUTM"], \
> #                        row["pFaultLowFX1"], row["pFaultHighFX1"], 
> row["repDistribution"],row["repDurMinMode"], \
> #                        row["repDurHigh"],row["repDurLow"], 
> row["repDurMinAvg"], row["repDurMinStdDev"]] )
>
> maintfault = [["ALL","ALL"],["NHRH","ALL"],["NHRH",4],["TTTT",3]]
>
> w1 = Wagon("NHRH",8)
> activate(w1,w1.storeme())
> w2 = Wagon("NHPH",7)
> activate(w2,w2.storeme())
> w3 = Wagon("TTTT",3)
> activate(w3,w3.storeme())
>
>
> u = Unit()
> activate(u,u.run()) 
>
>
>
> ------------------------------------------------------------------------------
> Come build with us! The BlackBerry(R) Developer Conference in SF, CA
> is the only developer event you need to attend this year. Jumpstart your
> developing skills, take BlackBerry mobile applications to market and stay 
> ahead of the curve. Join us from November 9 - 12, 2009. Register now!
> http://p.sf.net/sfu/devconference
> _______________________________________________
> Simpy-users mailing list
> Simpy-users <at> lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/simpy-users
>   

------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay 
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
Bonnie Douglas | 8 Oct 12:25

Re: Use of filter function on store

Klaus G. Muller <kgmuller <at> xs4all.nl> writes:

> 
> Bonnie,
> here is an example of how the filter function should be written:
> 
> from SimPy.Simulation import *
> import random as rand
> 
> class Parcel:
>     def __init__(self,parcelType):
>         self.ptype = parcelType
> 
> class ParcelProducer(Process):
>     def produce(self,store):
>         while True:
>             yield hold,self,1
>             parcl = Parcel(parcelType = rand.choice(["Light","Heavy"]))
>             yield put,self,store,[parcl]
> 
> class ParcelConsumer(Process):
>     def consume(self,store):
>         while True:
>             yield get,self,store,heavies
>             found = self.got
>             print "Time %s: retrieved parcel type is %s"%(now(),[x.ptype 
> for x in found])
> 
> def heavies(buff):
>     """filter function. Only get 'Heavy' parcels"""
>     res = []
>     for item in buff:
>         if item.ptype == "Heavy":
>             res.append(item)
>     return res
> 
> rand.seed(12345)
> initialize()
> s = Store(capacity = 1000)
> pp = ParcelProducer()
> activate(pp,pp.produce(store = s))
> pc =ParcelConsumer()
> activate(pc,pc.consume(store = s))
> simulate(until=15)
> print "Left in store: parcels of type: %s"%[x.ptype for x in s.theBuffer]
> 
> The filter function must have only one parameter (standing for the 
> Store's buffer). It must be in the scope of the "yield get" which uses it.
> 
> OK?
> 
> Klaus Müller

Hi Klaus,
Thank you very much for this example; it certainly makes the use of the filter
function more clear for me.

In this example you confirmed my suspicion that the filter function has a
hard-coded comparison (e.g., "Heavy").  I'd like to pass the filter function a
string of arguments from my consuming process (but i know that it doesn't take
any arguments except the storage buffer) since the objects that are stored have
several attributes I need to match.

Do I need to execute separate yield get statements for each argument with a
separate filter function defined for each of the possible alternatives?  A
friend suggested "currying", or use of the partial function application from
functools which seems to return a function from the function on the yield
statement.  So far, however, I haven't had success with this approach.  I
shudder at the thought of writing so many different filter functions to capture
each possible combination (and then I'm sure to miss some since the input file
is configurable by the user - it's supposed to be flexible).

Regards,
Bonnie

------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay 
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
_______________________________________________
Simpy-users mailing list
Simpy-users <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/simpy-users
Klaus G. Muller | 8 Oct 14:14
Picon
Picon
Favicon

Re: Use of filter function on store

Bonnie,
Hardwiring is not necessary. You can always use a global criteria as a parameter, like this:

from SimPy.Simulation import *
import random as rand

class Parcel:
    def __init__(self,parcelType):
        self.ptype = parcelType
       
class ParcelProducer(Process):
    def produce(self,store):
        while True:
            yield hold,self,1
            parcl = Parcel(parcelType = rand.choice(["Light","Heavy"]))
            yield put,self,store,[parcl]
           
class ParcelConsumer(Process):
    def consume(self,store):
        global criteria
        while True:
            criteria = "Heavy"
            yield get,self,store,filter
            found = self.got
            print "Time %s: retrieved parcel type is %s"%(now(),[x.ptype for x in found])
 
def filter(buff):
    """filter function. Only get parcels meeting criteria"""
    res = []
    for item in buff:
        if item.ptype == criteria:
            res.append(item)
    return res
           
rand.seed(12345)
initialize()
s = Store(capacity = 1000)
pp = ParcelProducer()
activate(pp,pp.produce(store = s))
pc =ParcelConsumer()
activate(pc,pc.consume(store = s))
simulate(until=15)
print "Left in store: parcels of type: %s"%[x.ptype for x in s.theBuffer]

That should do it, I think. You can also use a list as criteria and test with "if item.ptype in criteria". This gives you a logical "or" capability.

Regards,
Klaus Müller

Bonnie Douglas wrote:
Klaus G. Muller <kgmuller <at> xs4all.nl> writes:
Bonnie, here is an example of how the filter function should be written: from SimPy.Simulation import * import random as rand class Parcel: def __init__(self,parcelType): self.ptype = parcelType class ParcelProducer(Process): def produce(self,store): while True: yield hold,self,1 parcl = Parcel(parcelType = rand.choice(["Light","Heavy"])) yield put,self,store,[parcl] class ParcelConsumer(Process): def consume(self,store): while True: yield get,self,store,heavies found = self.got print "Time %s: retrieved parcel type is %s"%(now(),[x.ptype for x in found]) def heavies(buff): """filter function. Only get 'Heavy' parcels""" res = [] for item in buff: if item.ptype == "Heavy": res.append(item) return res rand.seed(12345) initialize() s = Store(capacity = 1000) pp = ParcelProducer() activate(pp,pp.produce(store = s)) pc =ParcelConsumer() activate(pc,pc.consume(store = s)) simulate(until=15) print "Left in store: parcels of type: %s"%[x.ptype for x in s.theBuffer] The filter function must have only one parameter (standing for the Store's buffer). It must be in the scope of the "yield get" which uses it. OK? Klaus Müller
Hi Klaus, Thank you very much for this example; it certainly makes the use of the filter function more clear for me. In this example you confirmed my suspicion that the filter function has a hard-coded comparison (e.g., "Heavy"). I'd like to pass the filter function a string of arguments from my consuming process (but i know that it doesn't take any arguments except the storage buffer) since the objects that are stored have several attributes I need to match. Do I need to execute separate yield get statements for each argument with a separate filter function defined for each of the possible alternatives? A friend suggested "currying", or use of the partial function application from functools which seems to return a function from the function on the yield statement. So far, however, I haven't had success with this approach. I shudder at the thought of writing so many different filter functions to capture each possible combination (and then I'm sure to miss some since the input file is configurable by the user - it's supposed to be flexible). Regards, Bonnie ------------------------------------------------------------------------------ Come build with us! The BlackBerry(R) Developer Conference in SF, CA is the only developer event you need to attend this year. Jumpstart your developing skills, take BlackBerry mobile applications to market and stay ahead of the curve. Join us from November 9 - 12, 2009. Register now! http://p.sf.net/sfu/devconference _______________________________________________ Simpy-users mailing list Simpy-users <at> lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/simpy-users
------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay 
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
_______________________________________________
Simpy-users mailing list
Simpy-users <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/simpy-users
Bonnie Douglas | 8 Oct 21:52

Re: Use of filter function on store

Klaus G. Muller <kgmuller <at> xs4all.nl> writes:

> 
> 
> Bonnie,
> Hardwiring is not necessary. You can always use a global criteria as a
> parameter, like this:from SimPy.Simulation import *
> import random as rand
> class Parcel:
>     def __init__(self,parcelType):
>         self.ptype = parcelType
>         
> class ParcelProducer(Process):
>     def produce(self,store):
>         while True:
>             yield hold,self,1
>             parcl = Parcel(parcelType = rand.choice(["Light","Heavy"]))
>             yield put,self,store,[parcl]
>             
> class ParcelConsumer(Process):
>     def consume(self,store):
>         global criteria
>         while True:
>             criteria = "Heavy"
>             yield get,self,store,filter
>             found = self.got
>             print "Time %s: retrieved parcel type is
> %s"%(now(),[x.ptype for x in found])
>  
> def filter(buff):
>     """filter function. Only get parcels meeting criteria"""
>     res = []
>     for item in buff:
>         if item.ptype == criteria:
>             res.append(item)
>     return res
>             
> rand.seed(12345)
> initialize()
> s = Store(capacity = 1000)
> pp = ParcelProducer()
> activate(pp,pp.produce(store = s))
> pc =ParcelConsumer()
> activate(pc,pc.consume(store = s))
> simulate(until=15)
> print "Left in store: parcels of type: %s"%[x.ptype for x in
> s.theBuffer]That should do it, I think. You can also use a list as criteria
> and test with "if item.ptype in criteria". This gives you a
> logical "or" capability.
> Regards,
> Klaus Müller

Hi Klaus,
I had originally rejected the concept of global variable because I was worried
that multiple consumer processes might need to use the variable at once.  If one
consumer has it set to "heavy" and the next has it set to "light" is it possible
that the consuming process that wants a "heavy" will wind up with a "light"?

Before I forget - I'm really enjoying working with SimPy!  Although working with
a functional programming language like Python is completely new for me (and a
bit weird at times), SimPy is extremely flexible.  I'm really interested to see
if I can get this model working well because we'll target use of SimPy more in
the future.  It's so nice to be free of the overhead of working with graphical
packages.
Cheers,
Bonnie

------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay 
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
_______________________________________________
Simpy-users mailing list
Simpy-users <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/simpy-users
Joel Welling | 8 Oct 22:24
Picon
Favicon

A bug in queue management during reneges in SimPy 2.0.1?

Hi folks;
  I have an application with a compound yield statement trying to do a
get from a Store, but with a renege clause.  As the application runs
I've seen many copies of the Process build up in the Store's getQ, with
a new one occurring every time the renege clause occurred.  I traced it
down to Simulation.py line 829, where the method
_Holder(Process).trigger(...) looks like:

            def trigger(self, delay):
                yield hold, self, delay
                #if not proc in b[2].activeQ:
                if proc in b[2].getQ:
                    a[1].sim.reactivate(proc)

Shouldn't proc also get removed from b[2].getQ?  I changed it to:

            def trigger(self, delay):
                yield hold, self, delay
                #if not proc in b[2].activeQ:
                if proc in b[2].getQ:
                    b[2].getQ.remove(proc)
                    a[1].sim.reactivate(proc)

and this change prevented the accumulation of Processes in my getQ.
I think there are other instances of the same issue in other _Holders
and _EventWaits.

-Joel
 welling <at> psc.edu

------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay 
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
Bonnie Douglas | 9 Oct 00:54

Taking all items out of a store

Hi,
I've run into some strange behaviour in a test module that I've written.  This
might be related to my earlier post on use of filters on a yield get.

I put 3 processes into my store.  When I remove all items from the store (and
verify the count is 3 items) in a single get and immediately print the
nrBuffered in the store after the get there is 1 item left (there should be 0).
 However, if I only remove 1 item then the nrBuffered is 2, which is correct.

Code and results (which are copied as comments in the code) are below.  Note:
due to my lack of experience with Python it is highly likely that I've done
something extremely silly.  I'm going to eliminate the wagon processes to see if
that might be the problem.
-------------------------------------------------------
from functools import partial
from SimPy.Simulation import *

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

    def run(self):           # the ProducerD PEM
        global wT, pS
        while True:
            for li in maintfault:
                wT = li[0]
                pS = li[1]
                print now(), self.name, sObj.nrBuffered, ' items in buffer',
'At', now(), ' I wanted type: ', wT, ' pack: ', pS
                #part = partial(wag_type_filter, wagon_type=wT, pack_size=pS)
                yield get, self, sObj, wag_type_filter
                print now(), self.name, " got "
                for o in self.got:
                    print o.wagType, o.pksize
                print now(), self.name, 'after got items there are ',
sObj.nrBuffered
                yield hold, self, 1 # wait for 1 units for the heck of it      

                #yield put, self, sObj, self.got #put them all back
                print now(), self.name, ' put some back so there are ',
sObj.nrBuffered, ' items in the buffer'

class Wagon(Process):
    def __init__(self,wType,pkSize):
        Process.__init__(self, wType, pkSize)
        self.moveSignal = SimEvent()
        self.pksize = pkSize
        self.wagType = wType
        self.now = now()
    def storeme(self):
        #print 'store: ', self.wagType, self.pksize
        yield put,self,sObj,[self]
        print now(), ' wagon process.  now have: ', sObj.nrBuffered
        yield waitevent,self,self.moveSignal
        yield hold, self, 10

def wag_type_filter(buff):
    """
    filter: get all wagons with type from store.
    """
    result=[]
    wagon_type = wT
    pack_size = pS
    print now(), 'in wagType function wagon_type: ', wagon_type, ' ps: ', pack_size
    if wagon_type == "ALL" and pack_size == "ALL":
        result = buff
    else:
        for i in buff:
            if wagon_type == "ALL":
                if i.pkSize == pack_size:
                    result.append(i)
            elif pack_size == "ALL":
                if i.wagType == wagon_type:
                    result.append(i)
    return result

initialize()
################################################
## read input data in from files
################################################
sObj = Store(name='a_store',
             unitName='wagons',
             capacity=9999,
             monitored=True,
             monitorType=Monitor)

# This list should result in 1 item being removed from the store.  Results show
that is the case.
maintfault = [["NHRH","ALL","brake",.1],["TTTT",3,"door",.15],["ALL", "ALL",
"wheel", .2]]
##0  wagon process.  now have:  1
##0  wagon process.  now have:  2
##0  wagon process.  now have:  3
##0 u1 3  items in buffer At 0  I wanted type:  NHRH  pack:  ALL
##0 in wagType function wagon_type:  NHRH  ps:  ALL
##0 u1  got 
##NHRH 8
##0 u1 after got items there are  2
##1 u1  put some back so there are  2  items in the buffer
##1 u1 2  items in buffer At 1  I wanted type:  TTTT  pack:  3
##1 in wagType function wagon_type:  TTTT  ps:  3
##simulation ended:  1

#maintfault = [["ALL", "ALL", "wheel",
.2],["NHRH","ALL","brake",.1],["TTTT",3,"door",.15]]
### this list should result in all items being removed from the store on the
first try.
### However, 1 is left as shown by these results copied from IDLE:
##0  wagon process.  now have:  1
##0  wagon process.  now have:  2
##0  wagon process.  now have:  3
##0 u1 3  items in buffer At 0  I wanted type:  ALL  pack:  ALL
##0 in wagType function wagon_type:  ALL  ps:  ALL
##0 u1  got 
##NHRH 8
##NHPH 7
##TTTT 3
##0 u1 after got items there are  1
##1 u1  put some back so there are  1  items in the buffer
##1 u1 1  items in buffer At 1  I wanted type:  NHRH  pack:  ALL
##1 in wagType function wagon_type:  NHRH  ps:  ALL
##simulation ended:  1

w1 = Wagon("NHRH",8)
activate(w1,w1.storeme())
w2 = Wagon("NHPH",7)
activate(w2,w2.storeme())
w3 = Wagon("TTTT",3)
activate(w3,w3.storeme())

u1 = Unit("u1")
activate(u1,u1.run())

#u2 = Unit("u2")
#activate(u2,u2.run())

simulate(until=60)
print 'simulation ended: ', now()

------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay 
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference

Gmane