"""simple docstring"""







import gc
import random
import tempfile
import unittest

import numpy as np
import torch
from PIL import Image
from transformers import CLIPTextConfig, CLIPTextModel, CLIPTokenizer

from diffusers import (
    AutoencoderKL,
    DDIMInverseScheduler,
    DDIMScheduler,
    DPMSolverMultistepInverseScheduler,
    DPMSolverMultistepScheduler,
    StableDiffusionDiffEditPipeline,
    UNetaDConditionModel,
)
from diffusers.utils import load_image, slow
from diffusers.utils.testing_utils import enable_full_determinism, floats_tensor, require_torch_gpu, torch_device

from ..pipeline_params import TEXT_GUIDED_IMAGE_INPAINTING_BATCH_PARAMS, TEXT_GUIDED_IMAGE_INPAINTING_PARAMS
from ..test_pipelines_common import PipelineLatentTesterMixin, PipelineTesterMixin


enable_full_determinism()







class        UpperCamelCase		(			lowercase_						,      lowercase_						,      unittest.TestCase  ):
   lowercase							=  StableDiffusionDiffEditPipeline
   lowercase							=  TEXT_GUIDED_IMAGE_INPAINTING_PARAMS - {'height', 'width', 'image'} | {'image_latents'}
   lowercase							=  TEXT_GUIDED_IMAGE_INPAINTING_BATCH_PARAMS - {'image'} | {'image_latents'}
   lowercase							=  frozenset(
       []  )  # TO-DO: update image_params once pipeline is refactored with VaeImageProcessor.preprocess
   lowercase							=  frozenset([]  )
   def 			_UpperCAmelCase   (			self			)	->      str:


        '''simple docstring'''


        torch.manual_seed(0			)
        lowercase_	:				Optional[int]													=	UNetaDConditionModel(
            block_out_channels=(32, 64)     ,layers_per_block=2     ,sample_size=32     ,in_channels=4     ,out_channels=4     ,down_block_types=('DownBlock2D', 'CrossAttnDownBlock2D')     ,up_block_types=('CrossAttnUpBlock2D', 'UpBlock2D')     ,cross_attention_dim=32     ,attention_head_dim=(2, 4)     ,use_linear_projection=__UpperCamelCase     ,)
        lowercase_	:				str													=	DDIMScheduler(
            beta_start=0.0_0085     ,beta_end=0.012     ,beta_schedule='scaled_linear'     ,clip_sample=__UpperCamelCase     ,set_alpha_to_one=__UpperCamelCase     ,)
        lowercase_	:				Union[str, Any]													=	DDIMInverseScheduler(
            beta_start=0.0_0085     ,beta_end=0.012     ,beta_schedule='scaled_linear'     ,clip_sample=__UpperCamelCase     ,set_alpha_to_zero=__UpperCamelCase     ,)
        torch.manual_seed(0			)
        lowercase_	:				Optional[Any]													=	AutoencoderKL(
            block_out_channels=[32, 64]     ,in_channels=3     ,out_channels=3     ,down_block_types=['DownEncoderBlock2D', 'DownEncoderBlock2D']     ,up_block_types=['UpDecoderBlock2D', 'UpDecoderBlock2D']     ,latent_channels=4     ,sample_size=128     ,)
        torch.manual_seed(0			)
        lowercase_	:				List[Any]													=	CLIPTextConfig(
            bos_token_id=0     ,eos_token_id=2     ,hidden_size=32     ,intermediate_size=37     ,layer_norm_eps=1e-05     ,num_attention_heads=4     ,num_hidden_layers=5     ,pad_token_id=1     ,vocab_size=1000     ,hidden_act='gelu'     ,projection_dim=512     ,)
        lowercase_	:				Union[str, Any]													=	CLIPTextModel(__UpperCamelCase			)
        lowercase_	:				Tuple													=	CLIPTokenizer.from_pretrained('hf-internal-testing/tiny-random-clip'			)

        lowercase_	:				Optional[int]													=	{
            'unet': unet,
            'scheduler': scheduler,
            'inverse_scheduler': inverse_scheduler,
            'vae': vae,
            'text_encoder': text_encoder,
            'tokenizer': tokenizer,
            'safety_checker': None,
            'feature_extractor': None,
        }

        return components
   def 			_UpperCAmelCase   (			self     ,__UpperCamelCase     ,__UpperCamelCase=0			)	->      Optional[Any]:


        '''simple docstring'''


        lowercase_	:				str													=	floats_tensor((1, 16, 16)     ,rng=random.Random(__UpperCamelCase			)			).to(__UpperCamelCase			)
        lowercase_	:				List[Any]													=	floats_tensor((1, 2, 4, 16, 16)     ,rng=random.Random(__UpperCamelCase			)			).to(__UpperCamelCase			)
        if str(__UpperCamelCase			).startswith('mps'			):
             lowercase_	:				Dict													=	torch.manual_seed(__UpperCamelCase			)
        else:
             lowercase_	:				Optional[Any]													=	torch.Generator(device=__UpperCamelCase			).manual_seed(__UpperCamelCase			)
        lowercase_	:				Tuple													=	{
            'prompt': 'a dog and a newt',
            'mask_image': mask,
            'image_latents': latents,
            'generator': generator,
            'num_inference_steps': 2,
            'inpaint_strength': 1.0,
            'guidance_scale': 6.0,
            'output_type': 'numpy',
        }

        return inputs
   def 			_UpperCAmelCase   (			self     ,__UpperCamelCase     ,__UpperCamelCase=0			)	->      Optional[Any]:


        '''simple docstring'''


        lowercase_	:				Optional[Any]													=	floats_tensor((1, 3, 32, 32)     ,rng=random.Random(__UpperCamelCase			)			).to(__UpperCamelCase			)
        lowercase_	:				Union[str, Any]													=	image.cpu().permute(0     ,2     ,3     ,1			)[0]
        lowercase_	:				Tuple													=	Image.fromarray(np.uinta(__UpperCamelCase			)			).convert('RGB'			)
        if str(__UpperCamelCase			).startswith('mps'			):
             lowercase_	:				List[Any]													=	torch.manual_seed(__UpperCamelCase			)
        else:
             lowercase_	:				Optional[int]													=	torch.Generator(device=__UpperCamelCase			).manual_seed(__UpperCamelCase			)
        lowercase_	:				Optional[int]													=	{
            'image': image,
            'source_prompt': 'a cat and a frog',
            'target_prompt': 'a dog and a newt',
            'generator': generator,
            'num_inference_steps': 2,
            'num_maps_per_mask': 2,
            'mask_encode_strength': 1.0,
            'guidance_scale': 6.0,
            'output_type': 'numpy',
        }

        return inputs
   def 			_UpperCAmelCase   (			self     ,__UpperCamelCase     ,__UpperCamelCase=0			)	->      Dict:


        '''simple docstring'''


        lowercase_	:				List[Any]													=	floats_tensor((1, 3, 32, 32)     ,rng=random.Random(__UpperCamelCase			)			).to(__UpperCamelCase			)
        lowercase_	:				Optional[int]													=	image.cpu().permute(0     ,2     ,3     ,1			)[0]
        lowercase_	:				Tuple													=	Image.fromarray(np.uinta(__UpperCamelCase			)			).convert('RGB'			)
        if str(__UpperCamelCase			).startswith('mps'			):
             lowercase_	:				str													=	torch.manual_seed(__UpperCamelCase			)
        else:
             lowercase_	:				List[Any]													=	torch.Generator(device=__UpperCamelCase			).manual_seed(__UpperCamelCase			)
        lowercase_	:				List[Any]													=	{
            'image': image,
            'prompt': 'a cat and a frog',
            'generator': generator,
            'num_inference_steps': 2,
            'inpaint_strength': 1.0,
            'guidance_scale': 6.0,
            'decode_latents': True,
            'output_type': 'numpy',
        }
        return inputs
   def 			_UpperCAmelCase   (			self			)	->      Any:


        '''simple docstring'''


        if not hasattr(self.pipeline_class     ,'_optional_components'			):
             return

        lowercase_	:				Tuple													=	self.get_dummy_components()
        lowercase_	:				List[str]													=	self.pipeline_class(**__UpperCamelCase			)
        pipe.to(__UpperCamelCase			)
        pipe.set_progress_bar_config(disable=__UpperCamelCase			)

        # set all optional components to None and update pipeline config accordingly
        for optional_component in pipe._optional_components:
             setattr(__UpperCamelCase     ,__UpperCamelCase     ,__UpperCamelCase			)
        pipe.register_modules(**{optional_component: None for optional_component in pipe._optional_components}			)

        lowercase_	:				str													=	self.get_dummy_inputs(__UpperCamelCase			)
        lowercase_	:				Dict													=	pipe(**__UpperCamelCase			)[0]

        with tempfile.TemporaryDirectory() as tmpdir:
             pipe.save_pretrained(__UpperCamelCase			)
             lowercase_	:				Union[str, Any]													=	self.pipeline_class.from_pretrained(__UpperCamelCase			)
             pipe_loaded.to(__UpperCamelCase			)
             pipe_loaded.set_progress_bar_config(disable=__UpperCamelCase			)

        for optional_component in pipe._optional_components:
             self.assertTrue(
                 getattr(__UpperCamelCase     ,__UpperCamelCase			) is None     ,f'''`{optional_component}` did not stay set to None after loading.'''     ,)

        lowercase_	:				Tuple													=	self.get_dummy_inputs(__UpperCamelCase			)
        lowercase_	:				List[Any]													=	pipe_loaded(**__UpperCamelCase			)[0]

        lowercase_	:				Any													=	np.abs(output - output_loaded			).max()
        self.assertLess(__UpperCamelCase     ,1e-4			)
   def 			_UpperCAmelCase   (			self			)	->      Dict:


        '''simple docstring'''


        lowercase_	:				List[Any]													=	'cpu'

        lowercase_	:				List[str]													=	self.get_dummy_components()
        lowercase_	:				List[str]													=	self.pipeline_class(**__UpperCamelCase			)
        pipe.to(__UpperCamelCase			)
        pipe.set_progress_bar_config(disable=__UpperCamelCase			)

        lowercase_	:				Optional[Any]													=	self.get_dummy_mask_inputs(__UpperCamelCase			)
        lowercase_	:				Tuple													=	pipe.generate_mask(**__UpperCamelCase			)
        lowercase_	:				Optional[Any]													=	mask[0, -3:, -3:]

        self.assertEqual(mask.shape     ,(1, 16, 16)			)
        lowercase_	:				int													=	np.array([0] * 9			)
        lowercase_	:				Tuple													=	np.abs(mask_slice.flatten() - expected_slice			).max()
        self.assertLessEqual(__UpperCamelCase     ,1e-3			)
        self.assertEqual(mask[0, -3, -4]     ,0			)
   def 			_UpperCAmelCase   (			self			)	->      Union[str, Any]:


        '''simple docstring'''


        lowercase_	:				int													=	'cpu'

        lowercase_	:				str													=	self.get_dummy_components()
        lowercase_	:				str													=	self.pipeline_class(**__UpperCamelCase			)
        pipe.to(__UpperCamelCase			)
        pipe.set_progress_bar_config(disable=__UpperCamelCase			)

        lowercase_	:				List[str]													=	self.get_dummy_inversion_inputs(__UpperCamelCase			)
        lowercase_	:				List[str]													=	pipe.invert(**__UpperCamelCase			).images
        lowercase_	:				Dict													=	image[0, -1, -3:, -3:]

        self.assertEqual(image.shape     ,(2, 32, 32, 3)			)
        lowercase_	:				Optional[Any]													=	np.array(
            [0.5150, 0.5134, 0.5043, 0.5376, 0.4694, 0.5_1050, 0.5015, 0.4407, 0.4799]     ,)
        lowercase_	:				Union[str, Any]													=	np.abs(image_slice.flatten() - expected_slice			).max()
        self.assertLessEqual(__UpperCamelCase     ,1e-3			)
   def 			_UpperCAmelCase   (			self			)	->      Union[str, Any]:


        '''simple docstring'''


        super().test_inference_batch_single_identical(expected_max_diff=5e-3			)







   def 			_UpperCAmelCase   (			self			)	->      str:


        '''simple docstring'''


        lowercase_	:				Any													=	'cpu'

        lowercase_	:				Any													=	self.get_dummy_components()

        lowercase_	:				Optional[int]													=	{'beta_start': 0.0_0085, 'beta_end': 0.012, 'beta_schedule': 'scaled_linear'}
        lowercase_	:				Optional[int]													=	DPMSolverMultistepScheduler(**__UpperCamelCase			)
        lowercase_	:				Dict													=	DPMSolverMultistepInverseScheduler(**__UpperCamelCase			)

        lowercase_	:				Optional[Any]													=	self.pipeline_class(**__UpperCamelCase			)
        pipe.to(__UpperCamelCase			)
        pipe.set_progress_bar_config(disable=__UpperCamelCase			)

        lowercase_	:				int													=	self.get_dummy_inversion_inputs(__UpperCamelCase			)
        lowercase_	:				str													=	pipe.invert(**__UpperCamelCase			).images
        lowercase_	:				Any													=	image[0, -1, -3:, -3:]

        self.assertEqual(image.shape     ,(2, 32, 32, 3)			)
        lowercase_	:				Tuple													=	np.array(
            [0.5150, 0.5134, 0.5043, 0.5376, 0.4694, 0.5_1050, 0.5015, 0.4407, 0.4799]     ,)
        lowercase_	:				Optional[int]													=	np.abs(image_slice.flatten() - expected_slice			).max()
        self.assertLessEqual(__UpperCamelCase     ,1e-3			)







@require_torch_gpu
@slow
class        UpperCamelCase		(			unittest.TestCase  ):
   def 			_UpperCAmelCase   (			self			)	->      int:


        '''simple docstring'''


        super().tearDown()
        gc.collect()
        torch.cuda.empty_cache()
   @classmethod
   def 			_UpperCAmelCase   (			cls			)	->      Dict:


        '''simple docstring'''


        lowercase_	:				Tuple													=	load_image(
            'https://huggingface.co/datasets/hf-internal-testing/diffusers-images/resolve/main/diffedit/fruit.png'			)

        lowercase_	:				Union[str, Any]													=	raw_image.convert('RGB'			).resize((768, 768)			)

        lowercase_	:				Dict													=	raw_image
   def 			_UpperCAmelCase   (			self			)	->      Dict:


        '''simple docstring'''


        lowercase_	:				List[str]													=	torch.manual_seed(0			)

        lowercase_	:				Optional[int]													=	StableDiffusionDiffEditPipeline.from_pretrained(
            'stabilityai/stable-diffusion-2-1'     ,safety_checker=__UpperCamelCase     ,torch_dtype=torch.floataa			)
        lowercase_	:				Optional[int]													=	DDIMScheduler.from_config(pipe.scheduler.config			)
        lowercase_	:				Tuple													=	DDIMInverseScheduler.from_config(pipe.scheduler.config			)
        pipe.enable_model_cpu_offload()
        pipe.set_progress_bar_config(disable=__UpperCamelCase			)

        lowercase_	:				Optional[Any]													=	'a bowl of fruit'
        lowercase_	:				Optional[int]													=	'a bowl of pears'

        lowercase_	:				str													=	pipe.generate_mask(
            image=self.raw_image     ,source_prompt=__UpperCamelCase     ,target_prompt=__UpperCamelCase     ,generator=__UpperCamelCase     ,)

        lowercase_	:				str													=	pipe.invert(
            prompt=__UpperCamelCase     ,image=self.raw_image     ,inpaint_strength=0.7     ,generator=__UpperCamelCase			).latents

        lowercase_	:				List[str]													=	pipe(
            prompt=__UpperCamelCase     ,mask_image=__UpperCamelCase     ,image_latents=__UpperCamelCase     ,generator=__UpperCamelCase     ,negative_prompt=__UpperCamelCase     ,inpaint_strength=0.7     ,output_type='numpy'     ,).images[0]

        lowercase_	:				Optional[int]													=	(
            np.array(
                load_image(
                    'https://huggingface.co/datasets/hf-internal-testing/diffusers-images/resolve/main'
                    '/diffedit/pears.png'			).resize((768, 768)			)			)
            / 255
        )
        assert np.abs((expected_image - image).max()			) < 5e-1







   def 			_UpperCAmelCase   (			self			)	->      List[str]:


        '''simple docstring'''


        lowercase_	:				Union[str, Any]													=	torch.manual_seed(0			)

        lowercase_	:				List[str]													=	StableDiffusionDiffEditPipeline.from_pretrained(
            'stabilityai/stable-diffusion-2-1'     ,safety_checker=__UpperCamelCase     ,torch_dtype=torch.floataa			)
        lowercase_	:				Optional[int]													=	DPMSolverMultistepScheduler.from_config(pipe.scheduler.config			)
        lowercase_	:				Any													=	DPMSolverMultistepInverseScheduler.from_config(pipe.scheduler.config			)
        pipe.enable_model_cpu_offload()
        pipe.set_progress_bar_config(disable=__UpperCamelCase			)

        lowercase_	:				List[str]													=	'a bowl of fruit'
        lowercase_	:				Optional[Any]													=	'a bowl of pears'

        lowercase_	:				Optional[Any]													=	pipe.generate_mask(
            image=self.raw_image     ,source_prompt=__UpperCamelCase     ,target_prompt=__UpperCamelCase     ,generator=__UpperCamelCase     ,)

        lowercase_	:				int													=	pipe.invert(
            prompt=__UpperCamelCase     ,image=self.raw_image     ,inpaint_strength=0.7     ,generator=__UpperCamelCase     ,num_inference_steps=25     ,).latents

        lowercase_	:				Any													=	pipe(
            prompt=__UpperCamelCase     ,mask_image=__UpperCamelCase     ,image_latents=__UpperCamelCase     ,generator=__UpperCamelCase     ,negative_prompt=__UpperCamelCase     ,inpaint_strength=0.7     ,num_inference_steps=25     ,output_type='numpy'     ,).images[0]

        lowercase_	:				Optional[int]													=	(
            np.array(
                load_image(
                    'https://huggingface.co/datasets/hf-internal-testing/diffusers-images/resolve/main'
                    '/diffedit/pears.png'			).resize((768, 768)			)			)
            / 255
        )
        assert np.abs((expected_image - image).max()			) < 5e-1


"""simple docstring"""







__SCREAMING_SNAKE_CASE    	={}



def 			lowercase__(       __SCREAMING_SNAKE_CASE							:     int     ,			__SCREAMING_SNAKE_CASE							:     int     ,			__SCREAMING_SNAKE_CASE							:     int      ):

     # if we are absent twice, or late 3 consecutive days,
     # no further prize strings are possible
     if late == 3 or absent == 2:
          return 0

     # if we have no days left, and have not failed any other rules,
     # we have a prize string
     if days == 0:
          return 1

     # No easy solution, so now we need to do the recursive calculation

     # First, check if the combination is already in the cache, and
     # if yes, return the stored value from there since we already
     # know the number of possible prize strings from this point on
     lowercase_	:				Any													=	(days, absent, late)
     if key in cache:
          return cache[key]

     # now we calculate the three possible ways that can unfold from
     # this point on, depending on our attendance today

     # 1) if we are late (but not absent), the "absent" counter stays as
     # it is, but the "late" counter increases by one
     lowercase_	:				Optional[int]													=	_calculate(days - 1     ,			__SCREAMING_SNAKE_CASE     ,			late + 1      )

     # 2) if we are absent, the "absent" counter increases by 1, and the
     # "late" counter resets to 0
     lowercase_	:				Any													=	_calculate(days - 1     ,			absent + 1     ,			0      )

     # 3) if we are on time, this resets the "late" counter and keeps the
     # absent counter
     lowercase_	:				Dict													=	_calculate(days - 1     ,			__SCREAMING_SNAKE_CASE     ,			0      )

     lowercase_	:				str													=	state_late + state_absent + state_ontime

     lowercase_	:				Tuple													=	prizestrings
     return prizestrings



def 			lowercase__(       __SCREAMING_SNAKE_CASE							:     int = 30      ):
     return _calculate(__SCREAMING_SNAKE_CASE     ,			absent=0     ,			late=0      )


if __name__ == "__main__":
       print(solution())

