import logging

# standard libraries
import sys

import numpy as np
import pytest  # type: ignore

# Custom/local libraries
from matrix import matrix_operation as matop

UpperCAmelCase							=							[[1_2, 1_0], [3, 9]]
UpperCAmelCase							=							[[3, 4], [7, 4]]
UpperCAmelCase							=							[[3, 0, 2], [2, 0, -2], [0, 1, 1]]
UpperCAmelCase							=							[[3, 0, -2], [2, 0, 2], [0, 1, 1]]
UpperCAmelCase							=							[[3, 0, 2], [2, 0, -2], [0, 1, 1], [2, 0, -2]]
UpperCAmelCase							=							[1]
UpperCAmelCase							=							[2]

UpperCAmelCase							=							logging.getLogger()
UpperCAmelCase							=							logging.DEBUG
UpperCAmelCase							=							logging.StreamHandler(sys.stdout)
logger.addHandler(stream_handler)






@pytest.mark.mat_ops
@pytest.mark.parametrize(
    ("mat1", "mat2") ,	[(mat_a, mat_b), (mat_c, mat_d), (mat_d, mat_e), (mat_f, mat_h)]     )
def 					SCREAMING_SNAKE_CASE_			(		lowerCAmelCase_: str ,	lowerCAmelCase_: Tuple     ):
      if (np.array(lowerCAmelCase_     )).shape < (2, 2) or (np.array(lowerCAmelCase_     )).shape < (2, 2):
            with pytest.raises(lowerCAmelCase_     ):
                  logger.info(f"\n\t{test_addition.__name__} returned integer"     )
                  matop.add(lowerCAmelCase_ ,	lowerCAmelCase_     )
      elif (np.array(lowerCAmelCase_     )).shape == (np.array(lowerCAmelCase_     )).shape:
            logger.info(f"\n\t{test_addition.__name__} with same matrix dims"     )
            snake_case_     :			Union[str, Any]       =       (np.array(lowerCAmelCase_     ) + np.array(lowerCAmelCase_     )).tolist()
            snake_case_     :			Optional[Any]       =       matop.add(lowerCAmelCase_ ,	lowerCAmelCase_     )
            assert theo == act
      else:
            with pytest.raises(lowerCAmelCase_     ):
                  logger.info(f"\n\t{test_addition.__name__} with different matrix dims"     )
                  matop.add(lowerCAmelCase_ ,	lowerCAmelCase_     )






@pytest.mark.mat_ops
@pytest.mark.parametrize(
    ("mat1", "mat2") ,	[(mat_a, mat_b), (mat_c, mat_d), (mat_d, mat_e), (mat_f, mat_h)]     )
def 					SCREAMING_SNAKE_CASE_			(		lowerCAmelCase_: Tuple ,	lowerCAmelCase_: Optional[int]     ):
      if (np.array(lowerCAmelCase_     )).shape < (2, 2) or (np.array(lowerCAmelCase_     )).shape < (2, 2):
            with pytest.raises(lowerCAmelCase_     ):
                  logger.info(f"\n\t{test_subtraction.__name__} returned integer"     )
                  matop.subtract(lowerCAmelCase_ ,	lowerCAmelCase_     )
      elif (np.array(lowerCAmelCase_     )).shape == (np.array(lowerCAmelCase_     )).shape:
            logger.info(f"\n\t{test_subtraction.__name__} with same matrix dims"     )
            snake_case_     :			Any       =       (np.array(lowerCAmelCase_     ) - np.array(lowerCAmelCase_     )).tolist()
            snake_case_     :			Optional[int]       =       matop.subtract(lowerCAmelCase_ ,	lowerCAmelCase_     )
            assert theo == act
      else:
            with pytest.raises(lowerCAmelCase_     ):
                  logger.info(f"\n\t{test_subtraction.__name__} with different matrix dims"     )
                  assert matop.subtract(lowerCAmelCase_ ,	lowerCAmelCase_     )






@pytest.mark.mat_ops
@pytest.mark.parametrize(
    ("mat1", "mat2") ,	[(mat_a, mat_b), (mat_c, mat_d), (mat_d, mat_e), (mat_f, mat_h)]     )
def 					SCREAMING_SNAKE_CASE_			(		lowerCAmelCase_: int ,	lowerCAmelCase_: Dict     ):
      if (np.array(lowerCAmelCase_     )).shape < (2, 2) or (np.array(lowerCAmelCase_     )).shape < (2, 2):
            logger.info(f"\n\t{test_multiplication.__name__} returned integer"     )
            with pytest.raises(lowerCAmelCase_     ):
                  matop.add(lowerCAmelCase_ ,	lowerCAmelCase_     )
      elif (np.array(lowerCAmelCase_     )).shape == (np.array(lowerCAmelCase_     )).shape:
            logger.info(f"\n\t{test_multiplication.__name__} meets dim requirements"     )
            snake_case_     :			Optional[int]       =       (np.matmul(lowerCAmelCase_ ,	lowerCAmelCase_     )).tolist()
            snake_case_     :			Optional[int]       =       matop.multiply(lowerCAmelCase_ ,	lowerCAmelCase_     )
            assert theo == act
      else:
            with pytest.raises(lowerCAmelCase_     ):
                  logger.info(
                      f"\n\t{test_multiplication.__name__} does not meet dim requirements"     )
                  assert matop.subtract(lowerCAmelCase_ ,	lowerCAmelCase_     )






@pytest.mark.mat_ops
def 					SCREAMING_SNAKE_CASE_			(		):
      snake_case_     :			Dict       =       (3.5 * np.array(lowerCAmelCase_     )).tolist()
      snake_case_     :			str       =       matop.scalar_multiply(lowerCAmelCase_ ,	3.5     )
      assert theo == act






@pytest.mark.mat_ops
def 					SCREAMING_SNAKE_CASE_			(		):
      snake_case_     :			Optional[Any]       =       (np.identity(5     )).tolist()
      snake_case_     :			Optional[Any]       =       matop.identity(5     )
      assert theo == act






@pytest.mark.mat_ops
@pytest.mark.parametrize("mat" ,	[mat_a, mat_b, mat_c, mat_d, mat_e, mat_f]     )
def 					SCREAMING_SNAKE_CASE_			(		lowerCAmelCase_: int     ):
      if (np.array(lowerCAmelCase_     )).shape < (2, 2):
            with pytest.raises(lowerCAmelCase_     ):
                  logger.info(f"\n\t{test_transpose.__name__} returned integer"     )
                  matop.transpose(lowerCAmelCase_     )
      else:
            snake_case_     :			Optional[int]       =       (np.transpose(lowerCAmelCase_     )).tolist()
            snake_case_     :			Optional[int]       =       matop.transpose(lowerCAmelCase_ ,	return_map=lowerCAmelCase_     )
            assert theo == act




from __future__ import annotations

UpperCAmelCase							=       "Alexander Joslin"






def 					SCREAMING_SNAKE_CASE_			(		lowerCAmelCase_: int     ):

      if number <= 0:
            snake_case_     :			Dict       =       f"n must be greater than 0. Got n = {number}"
            raise ValueError(lowerCAmelCase_     )

      snake_case_     :			Tuple       =       [number + 1] * (number + 1)

      # starting position
      snake_case_     :			Union[str, Any]       =       0
      for i in range(1 ,	lowerCAmelCase_     ):
            snake_case_     :			int       =       min(table[i + 1] ,	table[i] + 1     )
            # check if out of bounds
            if i * 2 <= number:
                  snake_case_     :			Tuple       =       min(table[i * 2] ,	table[i] + 1     )
            # check if out of bounds
            if i * 3 <= number:
                  snake_case_     :			Dict       =       min(table[i * 3] ,	table[i] + 1     )
      return table[number]


if __name__ == "__main__":
     import doctest

     doctest.testmod()



