






from transformers import BertTokenizer, EncoderDecoderModel, SeqaSeqTrainer, SeqaSeqTrainingArguments
from transformers.testing_utils import TestCasePlus, require_torch, slow
from transformers.utils import is_datasets_available


if is_datasets_available():
     import datasets







class 			snake_case__   (							__lowerCamelCase):

       '''simple docstring'''



       @slow
       @require_torch
       def 					__lowercase						(							self    ) ->      Any:






            '''simple docstring'''





            __snake_case			:str          =						EncoderDecoderModel.from_encoder_decoder_pretrained("""prajjwal1/bert-tiny"""			,						"""prajjwal1/bert-tiny"""    )
            __snake_case			:List[Any]          =						BertTokenizer.from_pretrained("""bert-base-uncased"""    )

            __snake_case			:Optional[int]          =						bertabert.config.encoder.vocab_size
            __snake_case			:Tuple          =						tokenizer.sep_token_id
            __snake_case			:int          =						tokenizer.cls_token_id
            __snake_case			:List[str]          =						1_28

            __snake_case			:int          =						datasets.load_dataset("""cnn_dailymail"""			,						"""3.0.0"""			,						split="""train[:1%]"""    )
            __snake_case			:Dict          =						datasets.load_dataset("""cnn_dailymail"""			,						"""3.0.0"""			,						split="""validation[:1%]"""    )

            __snake_case			:str          =						train_dataset.select(range(32    )    )
            __snake_case			:List[str]          =						val_dataset.select(range(16    )    )

            __snake_case			:str          =						4

            def _map_to_encoder_decoder_inputs(a__    ):
                 # Tokenizer will automatically set [BOS] <text> [EOS]
                 __snake_case			:Any          =						tokenizer(batch["""article"""]			,						padding="""max_length"""			,						truncation=UpperCamelCase_			,						max_length=5_12    )
                 __snake_case			:Union[str, Any]          =						tokenizer(batch["""highlights"""]			,						padding="""max_length"""			,						truncation=UpperCamelCase_			,						max_length=1_28    )
                 __snake_case			:Any          =						inputs.input_ids
                 __snake_case			:Dict          =						inputs.attention_mask

                 __snake_case			:Optional[int]          =						outputs.input_ids
                 __snake_case			:int          =						outputs.input_ids.copy()
                 __snake_case			:List[Any]          =						[
                     [-1_00 if token == tokenizer.pad_token_id else token for token in labels] for labels in batch["""labels"""]
                 ]
                 __snake_case			:str          =						outputs.attention_mask

                 assert all(len(UpperCamelCase_    ) == 5_12 for x in inputs.input_ids    )
                 assert all(len(UpperCamelCase_    ) == 1_28 for x in outputs.input_ids    )

                 return batch

            def _compute_metrics(a__    ):
                 __snake_case			:Optional[Any]          =						pred.label_ids
                 __snake_case			:Any          =						pred.predictions

                 # all unnecessary tokens are removed
                 __snake_case			:Union[str, Any]          =						tokenizer.batch_decode(UpperCamelCase_			,						skip_special_tokens=UpperCamelCase_    )
                 __snake_case			:List[Any]          =						tokenizer.batch_decode(UpperCamelCase_			,						skip_special_tokens=UpperCamelCase_    )

                 __snake_case			:Optional[Any]          =						sum([int(pred_str[i] == label_str[i]    ) for i in range(len(UpperCamelCase_    )    )]    ) / len(UpperCamelCase_    )

                 return {"accuracy": accuracy}

            # map train dataset
            __snake_case			:Optional[int]          =						train_dataset.map(
                _map_to_encoder_decoder_inputs			,						batched=UpperCamelCase_			,						batch_size=UpperCamelCase_			,						remove_columns=["""article""", """highlights"""]			,						)
            train_dataset.set_format(
                type="""torch"""			,						columns=["""input_ids""", """attention_mask""", """decoder_input_ids""", """decoder_attention_mask""", """labels"""]			,						)

            # same for validation dataset
            __snake_case			:List[Any]          =						val_dataset.map(
                _map_to_encoder_decoder_inputs			,						batched=UpperCamelCase_			,						batch_size=UpperCamelCase_			,						remove_columns=["""article""", """highlights"""]			,						)
            val_dataset.set_format(
                type="""torch"""			,						columns=["""input_ids""", """attention_mask""", """decoder_input_ids""", """decoder_attention_mask""", """labels"""]			,						)

            __snake_case			:Dict          =						self.get_auto_remove_tmp_dir()

            __snake_case			:Optional[int]          =						SeqaSeqTrainingArguments(
                output_dir=UpperCamelCase_			,						per_device_train_batch_size=UpperCamelCase_			,						per_device_eval_batch_size=UpperCamelCase_			,						predict_with_generate=UpperCamelCase_			,						evaluation_strategy="""steps"""			,						do_train=UpperCamelCase_			,						do_eval=UpperCamelCase_			,						warmup_steps=0			,						eval_steps=2			,						logging_steps=2			,						)

            # instantiate trainer
            __snake_case			:Optional[int]          =						SeqaSeqTrainer(
                model=UpperCamelCase_			,						args=UpperCamelCase_			,						compute_metrics=_compute_metrics			,						train_dataset=UpperCamelCase_			,						eval_dataset=UpperCamelCase_			,						tokenizer=UpperCamelCase_			,						)

            # start training
            trainer.train()










import math

lowerCamelCase__							=     10
lowerCamelCase__							=     7
lowerCamelCase__							=     BALLS_PER_COLOUR * NUM_COLOURS






def   UpperCamelCase  (       snake_case__     :   int = 20  ):




     '''simple docstring'''






     __snake_case			:Dict          =						math.comb(snake_case__	,snake_case__  )
     __snake_case			:int          =						math.comb(NUM_BALLS - BALLS_PER_COLOUR	,snake_case__  )

     __snake_case			:List[str]          =						NUM_COLOURS * (1 - missing_colour / total)

     return f'''{result:.9f}'''


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


