input: from typing import List, Tuple
  
  def simplex_method(coefficients: List[float], constraints: List[Tuple[float]], rhs: List[float], maximize: bool = True) -> Tuple[float, List[float]]:
      """
      Solve a linear programming problem using the Simplex method.
      
      Parameters:
      - coefficients: List of coefficients for the objective function.
      - constraints: List of tuples where each tuple represents the coefficients of a constraint equation.
      - rhs: List of right-hand side values for the constraints.
      - maximize: Boolean indicating whether to maximize (True) or minimize (False) the objective function.
      
      Returns:
      - A tuple containing the optimal value of the objective function and the optimal values of the decision variables.
      
      Example:
      For the problem:
      Maximize: 3x + 4y
      Constraints:
          2x + y <= 18
          x + 2y <= 16
          x >= 0
          y >= 0
      
      >> simplex_method([3, 4], [(2, 1), (1, 2)], [18, 16], maximize=True)
      (40.0, [8.0, 4.0])
      """
      pass  # Implementation of the Simplex method would go here
output:     
      import numpy as np
  
      def simplex_method(coefficients: List[float], constraints: List[Tuple[float]], rhs: List[float], maximize: bool = True) -> Tuple[float, List[float]]:
          num_vars = len(coefficients)
          num_constraints = len(constraints)
          
          # Initialize the tableau
          tableau = np.zeros((num_constraints + 1, num_vars + num_constraints + 1))
          tableau[0, :num_vars] = coefficients if maximize else [-c for c in coefficients]
          tableau[1:, :num_vars] = constraints
          tableau[1:, num_vars:num_vars + num_constraints] = np.identity(num_constraints)
          tableau[1:, -1] = rhs
          
          while True:
              # Find the entering variable
              entering_col = np.argmin(tableau[0, :-1])
              if tableau[0, entering_col] >= 0:
                  break
              
              # Find the leaving variable
              ratios = tableau[1:, -1] / tableau[1:, entering_col]
              ratios[ratios <= 0] = np.inf
              leaving_row = np.argmin(ratios) + 1
              if np.all(ratios == np.inf):
                  raise ValueError("Unbounded problem")
              
              # Pivot
              pivot_element = tableau[leaving_row, entering_col]
              tableau[leaving_row, :] /= pivot_element
              for i in range(num_constraints + 1):
                  if i != leaving_row:
                      tableau[i, :] -= tableau[i, entering_col] * tableau[leaving_row, :]
          
          # Extract the solution
          optimal_value = tableau[0, -1]
          optimal_vars = [0.0] * num_vars
          for i in range(num_constraints):
              if tableau[i + 1, -1] > 0:
                  optimal_vars[np.argmax(tableau[i + 1, :num_vars])] = tableau[i + 1, -1]
          
          return optimal_value, optimal_vars
  