

import numpy




class      UpperCamelCase :

    def __init__(			self :      Union[str, Any]							,    snake_case__ :      numpy.ndarray							,    snake_case__ :      numpy.ndarray    ):

     """simple docstring"""






     SCREAMING_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.
     SCREAMING_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.
     SCREAMING_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.
     SCREAMING_SNAKE_CASE								=			numpy.random.rand(3							,    1    )

     # Real output values provided.
     SCREAMING_SNAKE_CASE								=			output_array

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

    def UpperCamelCase			(			self :      Optional[Any]    ):

     """simple docstring"""






     SCREAMING_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.
     SCREAMING_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.
     SCREAMING_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 :      str    ):

     """simple docstring"""






     SCREAMING_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    )							,    )
     SCREAMING_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    )							,    )
     SCREAMING_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 :      Union[str, Any]							,    snake_case__ :      numpy.ndarray							,    snake_case__ :      int							,    snake_case__ :      bool    ):

     """simple docstring"""






     for iteration in range(1							,    iterations + 1    ):
      SCREAMING_SNAKE_CASE								=			self.feedforward()
      self.back_propagation()
      if give_loss:
       SCREAMING_SNAKE_CASE								=			numpy.mean(numpy.square(output - self.feedforward()    )    )
       print(F"""Iteration {iteration} Loss: {loss}"""    )




    def UpperCamelCase			(			self :      str							,    snake_case__ :      numpy.ndarray    ):

     """simple docstring"""






     SCREAMING_SNAKE_CASE								=			input_arr

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

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

     SCREAMING_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    (       _UpperCamelCase		:  numpy.ndarray	)		->							numpy.ndarray:
 '''simple docstring'''


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


def        __lowerCAmelCase    (       _UpperCamelCase		:  numpy.ndarray	)		->							numpy.ndarray:
 '''simple docstring'''


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


def        __lowerCAmelCase    (       )		->							int:
 '''simple docstring'''


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

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

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

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


if __name__ == "__main__":
      example()




def        __lowerCAmelCase    (       _UpperCamelCase		:  int	)		->							int:
 '''simple docstring'''


 SCREAMING_SNAKE_CASE								=			abs(_UpperCamelCase	)
 SCREAMING_SNAKE_CASE								=			0
 while n > 0:
  res += n % 10
  n //= 10
 return res


def        __lowerCAmelCase    (       _UpperCamelCase		:  int	)		->							int:
 '''simple docstring'''


 SCREAMING_SNAKE_CASE								=			abs(_UpperCamelCase	)
 return n if n < 10 else n % 10 + sum_of_digits(n // 10	)


def        __lowerCAmelCase    (       _UpperCamelCase		:  int	)		->							int:
 '''simple docstring'''


 return sum(int(_UpperCamelCase	) for c in str(abs(_UpperCamelCase	)	)	)


def        __lowerCAmelCase    (       )		->							None:
 '''simple docstring'''


 from collections.abc import Callable
 from timeit import timeit

 def benchmark_a_function(_UpperCamelCase		:  Callable		,							_UpperCamelCase		:  int	) -> None:
  SCREAMING_SNAKE_CASE								=			f"""{func.__name__}({value})"""
  SCREAMING_SNAKE_CASE								=			timeit(f"""__main__.{call}"""		,							setup='import __main__'	)
  print(f"""{call:56} = {func(_UpperCamelCase	)} -- {timing:.4f} seconds"""	)

 for value in (26_21_44, 11_25_89_99_06_84_26_24, 1_26_76_50_60_02_28_22_94_01_49_67_03_20_53_76):
  for func in (sum_of_digits, sum_of_digits_recursion, sum_of_digits_compact):
   benchmark_a_function(_UpperCamelCase		,							_UpperCamelCase	)
  print()


if __name__ == "__main__":
      import doctest

      doctest.testmod()
      benchmark()

