





'''simple docstring'''






import numpy




class 					UpperCAmelCase	:




      def __init__(     self     :					int     ,     __snake_case     :					numpy.ndarray     ,     __snake_case     :					numpy.ndarray    )							-> None:
            _lowerCAmelCase					=				input_array

            # Random initial weights are assigned where first argument is the
            # number of nodes in previous layer and second argument is the
            # number of nodes in the next layer.

            # Random initial weights are assigned.
            # self.input_array.shape[1] is used to represent number of nodes in input layer.
            # First hidden layer consists of 4 nodes.
            _lowerCAmelCase					=				numpy.random.rand(
                self.input_array.shape[1]     ,     4    )

            # Random initial values for the first hidden layer.
            # First hidden layer has 4 nodes.
            # Second hidden layer has 3 nodes.
            _lowerCAmelCase					=				numpy.random.rand(
                4     ,     3    )

            # Random initial values for the second hidden layer.
            # Second hidden layer has 3 nodes.
            # Output layer has 1 node.
            _lowerCAmelCase					=				numpy.random.rand(3     ,     1    )

            # Real output values provided.
            _lowerCAmelCase					=				output_array

            # Predicted output values by the neural network.
            # Predicted_output array initially consists of zeroes.
            _lowerCAmelCase					=				numpy.zeros(output_array.shape    )




      def 							lowercase__       (     self     :					List[Any]    )							-> numpy.ndarray:
            _lowerCAmelCase					=				sigmoid(
                numpy.dot(self.input_array     ,     self.input_layer_and_first_hidden_layer_weights    )    )

            # layer_between_first_hidden_layer_and_second_hidden_layer is the layer
            # connecting the first hidden set of nodes with the second hidden set of nodes.
            _lowerCAmelCase					=				sigmoid(
                numpy.dot(
                    self.layer_between_input_and_first_hidden_layer     ,     self.first_hidden_layer_and_second_hidden_layer_weights     ,     )    )

            # layer_between_second_hidden_layer_and_output is the layer connecting
            # second hidden layer with the output node.
            _lowerCAmelCase					=				sigmoid(
                numpy.dot(
                    self.layer_between_first_hidden_layer_and_second_hidden_layer     ,     self.second_hidden_layer_and_output_layer_weights     ,     )    )

            return self.layer_between_second_hidden_layer_and_output




      def 							lowercase__       (     self     :					Dict    )							-> None:
            _lowerCAmelCase					=				numpy.dot(
                self.layer_between_first_hidden_layer_and_second_hidden_layer.T     ,     2
                * (self.output_array - self.predicted_output)
                * sigmoid_derivative(self.predicted_output    )     ,     )
            _lowerCAmelCase					=				numpy.dot(
                self.layer_between_input_and_first_hidden_layer.T     ,     numpy.dot(
                    2
                    * (self.output_array - self.predicted_output)
                    * sigmoid_derivative(self.predicted_output    )     ,     self.second_hidden_layer_and_output_layer_weights.T     ,     )
                * sigmoid_derivative(
                    self.layer_between_first_hidden_layer_and_second_hidden_layer    )     ,     )
            _lowerCAmelCase					=				numpy.dot(
                self.input_array.T     ,     numpy.dot(
                    numpy.dot(
                        2
                        * (self.output_array - self.predicted_output)
                        * sigmoid_derivative(self.predicted_output    )     ,     self.second_hidden_layer_and_output_layer_weights.T     ,     )
                    * sigmoid_derivative(
                        self.layer_between_first_hidden_layer_and_second_hidden_layer    )     ,     self.first_hidden_layer_and_second_hidden_layer_weights.T     ,     )
                * sigmoid_derivative(self.layer_between_input_and_first_hidden_layer    )     ,     )

            self.input_layer_and_first_hidden_layer_weights += (
                updated_input_layer_and_first_hidden_layer_weights
            )
            self.first_hidden_layer_and_second_hidden_layer_weights += (
                updated_first_hidden_layer_and_second_hidden_layer_weights
            )
            self.second_hidden_layer_and_output_layer_weights += (
                updated_second_hidden_layer_and_output_layer_weights
            )




      def 							lowercase__       (     self     :					Tuple     ,     __snake_case     :					numpy.ndarray     ,     __snake_case     :					int     ,     __snake_case     :					bool    )							-> None:
            for iteration in range(1     ,     iterations + 1    ):
                  _lowerCAmelCase					=				self.feedforward()
                  self.back_propagation()
                  if give_loss:
                        _lowerCAmelCase					=				numpy.mean(numpy.square(output - self.feedforward()    )    )
                        print(f"Iteration {iteration} Loss: {loss}"    )




      def 							lowercase__       (     self     :					List[str]     ,     __snake_case     :					numpy.ndarray    )							-> int:
            _lowerCAmelCase					=				input_arr

            _lowerCAmelCase					=				sigmoid(
                numpy.dot(self.array     ,     self.input_layer_and_first_hidden_layer_weights    )    )

            _lowerCAmelCase					=				sigmoid(
                numpy.dot(
                    self.layer_between_input_and_first_hidden_layer     ,     self.first_hidden_layer_and_second_hidden_layer_weights     ,     )    )

            _lowerCAmelCase					=				sigmoid(
                numpy.dot(
                    self.layer_between_first_hidden_layer_and_second_hidden_layer     ,     self.second_hidden_layer_and_output_layer_weights     ,     )    )

            return int(self.layer_between_second_hidden_layer_and_output > 0.6    )




def   UpperCamelCase__ (						lowerCAmelCase    ):





      """simple docstring"""


      return 1 / (1 + numpy.exp(-value    ))
def   UpperCamelCase__ (						lowerCAmelCase    ):





      """simple docstring"""


      return (value) * (1 - (value))
def   UpperCamelCase__ (						):





      """simple docstring"""


      _lowerCAmelCase					=				numpy.array(
          (
              [0, 0, 0],
              [0, 0, 1],
              [0, 1, 0],
              [0, 1, 1],
              [1, 0, 0],
              [1, 0, 1],
              [1, 1, 0],
              [1, 1, 1],
          )				,      dtype=numpy.floataa				,      )

      # True output values for the given input values.
      _lowerCAmelCase					=				numpy.array(([0], [1], [1], [0], [1], [0], [0], [1])				,      dtype=numpy.floataa    )

      # Calling neural network class.
      _lowerCAmelCase					=				TwoHiddenLayerNeuralNetwork(
          input_array=lowerCAmelCase				,      output_array=lowerCAmelCase    )

      # Calling training function.
      # Set give_loss to True if you want to see loss in every iteration.
      neural_network.train(output=lowerCAmelCase				,      iterations=10				,      give_loss=lowerCAmelCase    )

      return neural_network.predict(numpy.array(([1, 1, 1])				,      dtype=numpy.floataa    )    )


if __name__ == "__main__":
      example()













'''simple docstring'''






class 					UpperCAmelCase	:




      def __init__(     self     :					List[str]     ,     __snake_case     :					str    )							-> Union[str, Any]:
            _lowerCAmelCase					=				val
            _lowerCAmelCase					=				None
            _lowerCAmelCase					=				None




      def 							lowercase__       (     self     :					Optional[Any]     ,     __snake_case     :					int    )							-> Optional[int]:
            if self.val:
                  if val < self.val:
                        if self.left is None:
                              _lowerCAmelCase					=				Node(__snake_case    )
                        else:
                              self.left.insert(__snake_case    )
                  elif val > self.val:
                        if self.right is None:
                              _lowerCAmelCase					=				Node(__snake_case    )
                        else:
                              self.right.insert(__snake_case    )
            else:
                  _lowerCAmelCase					=				val




def   UpperCamelCase__ (						lowerCAmelCase				,      lowerCAmelCase    ):





      """simple docstring"""


      if root:
            inorder(root.left				,      lowerCAmelCase    )
            res.append(root.val    )
            inorder(root.right				,      lowerCAmelCase    )
def   UpperCamelCase__ (						lowerCAmelCase    ):





      """simple docstring"""


      if len(lowerCAmelCase    ) == 0:
            return arr
      _lowerCAmelCase					=				Node(arr[0]    )
      for i in range(1				,      len(lowerCAmelCase    )    ):
            root.insert(arr[i]    )
      # Traverse BST in order.
      _lowerCAmelCase					=				[]
      inorder(lowerCAmelCase				,      lowerCAmelCase    )
      return res


if __name__ == "__main__":
      print(tree_sort([10, 1, 3, 2, 9, 14, 13]))






