simpy 2.2 examples in 3.0
Question: I am trying to work through some of the examples of simpy 2.2 (see:
<https://pythonhosted.org/SimPy/Tutorials/TheBank2OO.html>) and rewrite them
using simpy 3.0 lexicon (see:
<http://simpy.readthedocs.io/en/latest/about/history.html>). Has anybody came
across the the following example (bank door opens) rewritten for 3.0? Im not
entirely sure how to write the "self.sim.door_open" in the "customer" class as
an event using simpy 3.0.

    
    
    from SimPy.Simulation import     Simulation,Process,Resource,hold,waituntil,request,release
    from random import expovariate,seed
    
    ##Model components ------------------------
    
    class Doorman(Process):                                       
        """ Doorman opens the door"""
        def openthedoor(self):
            """ He will open the door when he arrives"""
            yield hold,self,expovariate(1.0/10.0)                 
            self.sim.door = 'Open'                                           
            print "%7.4f Doorman: Ladies and "\
                  "Gentlemen! You may all enter."%(self.sim.now(),)
    
    class Source(Process):                                        
        """ Source generates customers randomly"""
        def generate(self,number,rate):       
            for i in range(number):
                c = Customer(name = "Customer%02d"%(i,),sim=self.sim)
                self.sim.activate(c,c.visit(timeInBank=12.0))
                yield hold,self,expovariate(rate)
    
    class Customer(Process):                                      
        """ Customer arrives, is served and leaves """
        def visit(self,timeInBank=10):       
            arrive = self.sim.now()
    
            if self.sim.dooropen():
                msg = ' and the door is open.'         
            else:
                msg = ' but the door is shut.'
            print "%7.4f %s: Here I am%s"%(self.sim.now(),self.name,msg)
    
            yield waituntil,self,self.sim.dooropen                         
    
            print "%7.4f %s: I can  go in!"%(self.sim.now(),self.name)     
            wait = self.sim.now()-arrive
            print "%7.4f %s: Waited %6.3f"%(self.sim.now(),self.name,wait)
    
            yield request,self,self.sim.counter
            tib = expovariate(1.0/timeInBank)
            yield hold,self,tib
            yield release,self,self.sim.counter
    
            print "%7.4f %s: Finished    "%(self.sim.now(),self.name)                                 
    
    ## Model  ----------------------------------
    
    class BankModel(Simulation):
        def dooropen(self):                                               
            return self.door=='Open'
    
        def run(self,aseed):
            self.initialize()
            seed(aseed)
            self.counter = Resource(capacity=1,name="Clerk",sim=self)
            self.door = 'Shut'
            doorman=Doorman(sim=self)                                          
            self.activate(doorman,doorman.openthedoor())                    
            source = Source(sim=self)                                                         
            self.activate(source,
                 source.generate(number=5,rate=0.1),at=0.0)    
            self.simulate(until=400.0)
    
    ## Experiment data -------------------------
    
    maxTime = 2000.0   # minutes    
    seedVal = 393939
    
    ## Experiment  ----------------------------------
    
    BankModel().run(aseed=seedVal)
    

What i have so far, but i get the error "Environment object has no attribute
'door_open'"

    
    
    import simpy
    import random
    

Ninja edit: I managed to get the simulation to run, however i cant get the
door to initialize as "closed" then open at some point.

    
    
    def openthedoor(self):
        yield self.timeout(random.expovariate(1.0 /10.0))
        print('%7.4f Doorman: ladies and gentleman you may enter' %(self.now))
    
    
    
    def source(env, name, counter):
    
         for i in range(500):
            env.process(customer(env, 'Customer%02d' % i, counter,      time_in_queue=30.0))
            t = random.expovariate(1.0 / 20.0)
            yield env.timeout(t)
    
    def customer(env, name, counter, time_in_queue):
        arrive = env.now
    
        if env.process.openthedoor(env):
            msg = 'and the door is open'
        else:
            msg = 'but the door is sht'
            print('%7.4f %s: Customer has entered queue and' % (arrive, name, msg))
    
        yield env.process(openthedoor(env))
        print('%7.4f %s: I can go in' % (env.now, name))
        wait = env.now - arrive
        print('%7.4f %s: Waited %6.3f' % (env.now, name, wait))
    
        with counter.request() as req:
            # Wait for the counter or abort at the end of our tether
            yield req 
            waited = env.now - arrive
            tib = random.expovariate(1.0 / 20.0)
            yield env.timeout(tib)
            print('%7.4f %s: Waited %6.3f' % (env.now, name, waited))
            print('%7.4f %s: Finished' % (env.now, name))
    
    print('Batch Record Review Simulation')
    random.seed(RANDOM_SEED)
    env = simpy.Environment()
    data = []
    counter = simpy.Resource(env, capacity=1)
    env.process(source(env, CUSTOMERS, counter))
    # Start processes and run
    
    
    env.run(until=SIM_TIME)
    


Answer: In SimPy 2, `waituntil` used “busy waiting”, that means it checked at each
step if the condition evaluates to `True`. That is not very good practice and
may consume a lot of CPU time. That’s why this is no longer in SimPy 3.

In SimPy 3, you would use a normal `Event` (as createed by
`Environmanet.event()`). You could, for example, create a `Door` class and
pass a reference to the door instance to the door opener and the customer(s).
The customer could do a `door.open = env.event()` everytime they want to open
the door. The door opener would then trigger that event.

An alternative solution might be to use a `PriorityResource` (or maybe
`PreemptiveResource) as door. The door opener uses a higher priority than the
customers and is thus able to “block” the door (== door closed). Once the door
opener releases the resource, the next customer can “open” the door.

