


import numpy







class lowerCAmelCase_						:

 '''simple docstring'''

 def __init__(     self		,				_UpperCAmelCase		,				_UpperCAmelCase ):
       snake_case_	=				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.
       snake_case_	=				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.
       snake_case_	=				numpy.random.rand(
           4		,				3 )

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

       # Real output values provided.
       snake_case_	=				output_array

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



 def 						UpperCamelCase__					(     self ):
       snake_case_	=				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.
       snake_case_	=				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.
       snake_case_	=				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 						UpperCamelCase__					(     self ):
       snake_case_	=				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 )		,				)
       snake_case_	=				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 )		,				)
       snake_case_	=				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 						UpperCamelCase__					(     self		,				_UpperCAmelCase		,				_UpperCAmelCase		,				_UpperCAmelCase ):
       for iteration in range(1		,				iterations + 1 ):
             snake_case_	=				self.feedforward()
             self.back_propagation()
             if give_loss:
                   snake_case_	=				numpy.mean(numpy.square(output - self.feedforward() ) )
                   print(F'''Iteration {iteration} Loss: {loss}''' )





 def 						UpperCamelCase__					(     self		,				_UpperCAmelCase ):
       snake_case_	=				input_arr

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

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

       snake_case_	=				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 	__lowerCAmelCase   (SCREAMING_SNAKE_CASE )->  numpy.ndarray:




      """simple docstring"""

      return 1 / (1 + numpy.exp(-value ))






def 	__lowerCAmelCase   (SCREAMING_SNAKE_CASE )->  numpy.ndarray:




      """simple docstring"""

      return (value) * (1 - (value))






def 	__lowerCAmelCase   ()->  int:




      """simple docstring"""

      snake_case_	=				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.
      snake_case_	=				numpy.array(([0], [1], [1], [0], [1], [0], [0], [1]) , dtype=numpy.floataa )

      # Calling neural network class.
      snake_case_	=				TwoHiddenLayerNeuralNetwork(
          input_array=SCREAMING_SNAKE_CASE , output_array=SCREAMING_SNAKE_CASE )

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

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


if __name__ == "__main__":
   example()



def 	__lowerCAmelCase   (SCREAMING_SNAKE_CASE , SCREAMING_SNAKE_CASE )->  int:




      """simple docstring"""

      return x if y == 0 else greatest_common_divisor(SCREAMING_SNAKE_CASE , x % y )






def 	__lowerCAmelCase   (SCREAMING_SNAKE_CASE , SCREAMING_SNAKE_CASE )->  int:




      """simple docstring"""

      return (x * y) // greatest_common_divisor(SCREAMING_SNAKE_CASE , SCREAMING_SNAKE_CASE )






def 	__lowerCAmelCase   (SCREAMING_SNAKE_CASE = 20 )->  int:




      """simple docstring"""

      snake_case_	=				1
      for i in range(1 , n + 1 ):
            snake_case_	=				lcm(SCREAMING_SNAKE_CASE , SCREAMING_SNAKE_CASE )
      return g


if __name__ == "__main__":
   print(f'''{solution() = }''')