title: simpy resource availability schedule
body: <p>I'm using SimPy in Python to create a Discrete Event Simulation that requires resources to be available based on a schedule input by  the user in my case in a csv file. The aim is to represent different numbers of the same resource (e.g. staff) being available at different times of day. As far I as I can tell this isn't something that is available in base SimPy - like resource priorities. </p>
  
  <p>I have managed to get this working and have included the code below to show how. However I wanted to ask the community if there is a better way to achieve this functionality in SimPy? </p>
  
  <p>The code below works by requesting the resources at the start of each day for the times they are not supposed to be available - with a much higher priority to ensure they get the resource. The resources are then released at the appropriate times for use by other events/processes. As I say it works but seems wasteful with a lot of dummy processes working to ensure the correct true availability of resources. Any comments which would lead to improvements would be welcomed.</p>
  
  <p>so the csv looks like:</p>
  
  <pre><code>Number  time
  0        23
  50       22
  100      17
  50       10
  20       8
  5        6
  </code></pre>
  
  <p>where Number represents the number of staff that are the become available at the defined time. For example: There will be 5 staff from 6-8, 20 from 8-10, 50 from 10-17 and so on until the end of the day. </p>
  
  <p>The code:</p>
  
  <pre><code>import csv
  import simpy
  
  # empty list ready to hold the input data in the csv
  input_list = []
  
  # a dummy process that "uses" staff until the end of the current day
  def take_res():
      req = staff.request(priority=-100)
      yield req  # Request a staff resource at set priority
      yield test_env.timeout(24 - test_env.now)
  
  # A dummy process that "uses" staff for the time those staff should not 
  # be available for the real processes     
  def request_res(delay, avail_time):
      req = staff.request(priority=-100)
      yield req  # Request a staff resource at set priority
      yield test_env.timeout(delay)
      yield staff.release(req)
      # pass time it is avail for
      yield test_env.timeout(avail_time)
      test_env.process(take_res())
  
  # used to print current levels of resource usage
  def print_usage():
      print('At time %0.2f %d res are in use' % (test_env.now, staff.count))
      yield test_env.timeout(0.5)
      test_env.process(print_usage())
  
  # used to open the csv and read the data into a list
  with open('staff_schedule.csv', mode="r") as infile:
      reader = csv.reader(infile)
      next(reader, None)  # ignore header
      for row in reader:
          input_list.append(row[:2])
  
      # calculates the time the current number of resources will be 
      # available for and adds to the list 
  
      i = 0
      for row in the_list:
          if i == 0:
              row.append(24 - int(input_list[i][1]))
          else:
              row.append(int(input_list[i-1][1]) - int(input_list[i][1]))
  
          i += 1
  
      # converts list to tuple of tuples to prevent any accidental 
      # edits from this point in
      staff_tuple = tuple(tuple(row) for row in input_list)
      print(staff_tuple)
  
  # define environment and creates resources   
  test_env = simpy.Environment()
  staff = simpy.PriorityResource(test_env, capacity=sum(int(l[0]) for l in staff_tuple))
  
  # for each row in the tuple run dummy processes to hold resources 
  # according to schedule in the csv
  for item in the_tuple:
      print(item[0])
      for i in range(int(item[0])):
          test_env.process(request_res(int(item[1]), int(item[2])))
  
  # run event to print usage over time
  test_env.process(print_usage())
  
  # run for 25 hours - so 1 day
  test_env.run(until=25)
  </code></pre>