text: """
  Resource for sharing homogeneous matter between processes, either continuous
  (like water) or discrete (like apples).
  
  A :class:`Container` can be used to model the fuel tank of a gasoline station.
  Tankers increase and refuelled cars decrease the amount of gas in the station's
  fuel tanks.
  
  """
  from typing import TYPE_CHECKING, Optional, Union
  
  from simpy.core import BoundClass, Environment
  from simpy.resources import base
  
  
  ContainerAmount = Union[int, float]
  
  
  class ContainerPut(base.Put):
      """Request to put *amount* of matter into the *container*. The request will
      be triggered once there is enough space in the *container* available.
  
      Raise a :exc:`ValueError` if ``amount <= 0``.
  
      """
  
      def __init__(self, container: 'Container', amount: ContainerAmount):
          if amount <= 0:
              raise ValueError(f'amount(={amount}) must be > 0.')
          self.amount = amount
          """The amount of matter to be put into the container."""
  
          super().__init__(container)
  
  
  class ContainerGet(base.Get):
      """Request to get *amount* of matter from the *container*. The request will
      be triggered once there is enough matter available in the *container*.
  
      Raise a :exc:`ValueError` if ``amount <= 0``.
  
      """
  
      def __init__(self, container: 'Container', amount: ContainerAmount):
          if amount <= 0:
              raise ValueError(f'amount(={amount}) must be > 0.')
          self.amount = amount
          """The amount of matter to be taken out of the container."""
  
          super().__init__(container)
  
  
  class Container(base.BaseResource):
      """Resource containing up to *capacity* of matter which may either be
      continuous (like water) or discrete (like apples). It supports requests to
      put or get matter into/from the container.
  
      The *env* parameter is the :class:`~simpy.core.Environment` instance the
      container is bound to.
  
      The *capacity* defines the size of the container. By default, a container
      is of unlimited size. The initial amount of matter is specified by *init*
      and defaults to ``0``.
  
      Raise a :exc:`ValueError` if ``capacity <= 0``, ``init < 0`` or
      ``init > capacity``.
  
      """
  
      def __init__(
          self,
          env: Environment,
          capacity: ContainerAmount = float('inf'),
          init: ContainerAmount = 0,
      ):
          if capacity <= 0:
              raise ValueError('"capacity" must be > 0.')
          if init < 0:
              raise ValueError('"init" must be >= 0.')
          if init > capacity:
              raise ValueError('"init" must be <= "capacity".')
  
          super().__init__(env, capacity)
  
          self._level = init
  
      @property
      def level(self) -> ContainerAmount:
          """The current amount of the matter in the container."""
          return self._level
  
      if TYPE_CHECKING:
  
          def put(  # type: ignore[override] # noqa: F821
              self, amount: ContainerAmount
          ) -> ContainerPut:
              """Request to put *amount* of matter into the container."""
              return ContainerPut(self, amount)
  
          def get(  # type: ignore[override] # noqa: F821
              self, amount: ContainerAmount
          ) -> ContainerGet:
              """Request to get *amount* of matter out of the container."""
              return ContainerGet(self, amount)
  
      else:
          put = BoundClass(ContainerPut)
          get = BoundClass(ContainerGet)
  
      def _do_put(self, event: ContainerPut) -> Optional[bool]:
          if self._capacity - self._level >= event.amount:
              self._level += event.amount
              event.succeed()
              return True
          else:
              return None
  
      def _do_get(self, event: ContainerGet) -> Optional[bool]:
          if self._level >= event.amount:
              self._level -= event.amount
              event.succeed()
              return True
          else:
              return None
  