

import logging

# standard libraries
import sys

import numpy as np
import pytest  # type: ignore

# Custom/local libraries
from matrix import matrix_operation as matop

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

snake_case_					  =	logging.getLogger()
snake_case_					  =	logging.DEBUG
snake_case_					  =	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  __lowerCamelCase      (				SCREAMING_SNAKE_CASE_					:     Tuple  ,  SCREAMING_SNAKE_CASE_					:     Dict   )							->       Optional[int]:
      """simple docstring"""

      if (np.array(UpperCamelCase_   )).shape < (2, 2) or (np.array(UpperCamelCase_   )).shape < (2, 2):
            with pytest.raises(UpperCamelCase_   ):
                  logger.info(F"\n\t{test_addition.__name__} returned integer"   )
                  matop.add(UpperCamelCase_  ,  UpperCamelCase_   )
      elif (np.array(UpperCamelCase_   )).shape == (np.array(UpperCamelCase_   )).shape:
            logger.info(F"\n\t{test_addition.__name__} with same matrix dims"   )
            SCREAMING_SNAKE_CASE_				:      int					=	(np.array(UpperCamelCase_   ) + np.array(UpperCamelCase_   )).tolist()
            SCREAMING_SNAKE_CASE_				:      List[Any]					=	matop.add(UpperCamelCase_  ,  UpperCamelCase_   )
            assert theo == act
      else:
            with pytest.raises(UpperCamelCase_   ):
                  logger.info(F"\n\t{test_addition.__name__} with different matrix dims"   )
                  matop.add(UpperCamelCase_  ,  UpperCamelCase_   )


@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  __lowerCamelCase      (				SCREAMING_SNAKE_CASE_					:     Dict  ,  SCREAMING_SNAKE_CASE_					:     List[Any]   )							->       Union[str, Any]:
      """simple docstring"""

      if (np.array(UpperCamelCase_   )).shape < (2, 2) or (np.array(UpperCamelCase_   )).shape < (2, 2):
            with pytest.raises(UpperCamelCase_   ):
                  logger.info(F"\n\t{test_subtraction.__name__} returned integer"   )
                  matop.subtract(UpperCamelCase_  ,  UpperCamelCase_   )
      elif (np.array(UpperCamelCase_   )).shape == (np.array(UpperCamelCase_   )).shape:
            logger.info(F"\n\t{test_subtraction.__name__} with same matrix dims"   )
            SCREAMING_SNAKE_CASE_				:      Dict					=	(np.array(UpperCamelCase_   ) - np.array(UpperCamelCase_   )).tolist()
            SCREAMING_SNAKE_CASE_				:      Tuple					=	matop.subtract(UpperCamelCase_  ,  UpperCamelCase_   )
            assert theo == act
      else:
            with pytest.raises(UpperCamelCase_   ):
                  logger.info(F"\n\t{test_subtraction.__name__} with different matrix dims"   )
                  assert matop.subtract(UpperCamelCase_  ,  UpperCamelCase_   )


@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  __lowerCamelCase      (				SCREAMING_SNAKE_CASE_					:     Union[str, Any]  ,  SCREAMING_SNAKE_CASE_					:     Optional[int]   )							->       Optional[int]:
      """simple docstring"""

      if (np.array(UpperCamelCase_   )).shape < (2, 2) or (np.array(UpperCamelCase_   )).shape < (2, 2):
            logger.info(F"\n\t{test_multiplication.__name__} returned integer"   )
            with pytest.raises(UpperCamelCase_   ):
                  matop.add(UpperCamelCase_  ,  UpperCamelCase_   )
      elif (np.array(UpperCamelCase_   )).shape == (np.array(UpperCamelCase_   )).shape:
            logger.info(F"\n\t{test_multiplication.__name__} meets dim requirements"   )
            SCREAMING_SNAKE_CASE_				:      List[str]					=	(np.matmul(UpperCamelCase_  ,  UpperCamelCase_   )).tolist()
            SCREAMING_SNAKE_CASE_				:      Tuple					=	matop.multiply(UpperCamelCase_  ,  UpperCamelCase_   )
            assert theo == act
      else:
            with pytest.raises(UpperCamelCase_   ):
                  logger.info(
                      F"\n\t{test_multiplication.__name__} does not meet dim requirements"   )
                  assert matop.subtract(UpperCamelCase_  ,  UpperCamelCase_   )


@pytest.mark.mat_ops
def  __lowerCamelCase      (				)							->       str:
      """simple docstring"""

      SCREAMING_SNAKE_CASE_				:      Optional[int]					=	(3.5 * np.array(UpperCamelCase_   )).tolist()
      SCREAMING_SNAKE_CASE_				:      Optional[int]					=	matop.scalar_multiply(UpperCamelCase_  ,  3.5   )
      assert theo == act


@pytest.mark.mat_ops
def  __lowerCamelCase      (				)							->       List[str]:
      """simple docstring"""

      SCREAMING_SNAKE_CASE_				:      Union[str, Any]					=	(np.identity(5   )).tolist()
      SCREAMING_SNAKE_CASE_				:      Union[str, 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  __lowerCamelCase      (				SCREAMING_SNAKE_CASE_					:     Union[str, Any]   )							->       List[Any]:
      """simple docstring"""

      if (np.array(UpperCamelCase_   )).shape < (2, 2):
            with pytest.raises(UpperCamelCase_   ):
                  logger.info(F"\n\t{test_transpose.__name__} returned integer"   )
                  matop.transpose(UpperCamelCase_   )
      else:
            SCREAMING_SNAKE_CASE_				:      Optional[Any]					=	(np.transpose(UpperCamelCase_   )).tolist()
            SCREAMING_SNAKE_CASE_				:      Any					=	matop.transpose(UpperCamelCase_  ,  return_map=UpperCamelCase_   )
            assert theo == act




'''simple docstring'''






from __future__ import annotations

from PIL import Image

# Define the first generation of cells
# fmt: off
snake_case_					  =	[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]


def  __lowerCamelCase      (				SCREAMING_SNAKE_CASE_					:     int   )							->       list[int]:
      """simple docstring"""

      return [int(SCREAMING_SNAKE_CASE_   ) for c in F"{ruleset:08}"[:8]]


def  __lowerCamelCase      (				SCREAMING_SNAKE_CASE_					:     list[list[int]]  ,  SCREAMING_SNAKE_CASE_					:     list[int]  ,  SCREAMING_SNAKE_CASE_					:     int   )							->       list[int]:
      """simple docstring"""

      SCREAMING_SNAKE_CASE_				:      Optional[Any]					=	len(cells[0]   )  # 31
      SCREAMING_SNAKE_CASE_				:      Dict					=	[]
      for i in range(SCREAMING_SNAKE_CASE_   ):
            # Get the neighbors of each cell
            # Handle neighbours outside bounds by using 0 as their value
            SCREAMING_SNAKE_CASE_				:      Any					=	0 if i == 0 else cells[time][i - 1]
            SCREAMING_SNAKE_CASE_				:      Dict					=	0 if i == population - 1 else cells[time][i + 1]
            # Define a new cell and add it to the new generation
            SCREAMING_SNAKE_CASE_				:      List[Any]					=	7 - int(F"{left_neighbor}{cells[time][i]}{right_neighbor}"  ,  2   )
            next_generation.append(rule[situation]   )
      return next_generation


def  __lowerCamelCase      (				SCREAMING_SNAKE_CASE_					:     list[list[int]]   )							->       Image.Image:
      """simple docstring"""

      SCREAMING_SNAKE_CASE_				:      Tuple					=	Image.new("RGB"  ,  (len(cells[0]   ), len(SCREAMING_SNAKE_CASE_   ))   )
      SCREAMING_SNAKE_CASE_				:      Optional[int]					=	img.load()
      # Generates image
      for w in range(img.width   ):
            for h in range(img.height   ):
                  SCREAMING_SNAKE_CASE_				:      List[Any]					=	2_5_5 - int(2_5_5 * cells[h][w]   )
                  SCREAMING_SNAKE_CASE_				:      Optional[int]					=	(color, color, color)
      return img


if __name__ == "__main__":
      snake_case_					  =	bin(int(input('Rule:\n').strip()))[2:]
      snake_case_					  =	format_ruleset(int(rule_num))
      for time in range(1_6):
            CELLS.append(new_generation(CELLS, rule, time))
      snake_case_					  =	generate_image(CELLS)
      # Uncomment to save the image
      # img.save(f"rule_{rule_num}.png")
      img.show()

