


'''simple docstring'''



from math import factorial






def   lowerCamelCase							(_SCREAMING_SNAKE_CASE      :   int						,      _SCREAMING_SNAKE_CASE      :   int   ):

					# If either of the conditions are true, the function is being asked
					# to calculate a factorial of a negative number, which is not possible
					if n < k or k < 0:
										raise ValueError('Please enter positive integers for n and k where n >= k'   )
					return factorial(_SCREAMING_SNAKE_CASE   ) // (factorial(_SCREAMING_SNAKE_CASE   ) * factorial(n - k   ))


if __name__ == "__main__":
	print(
	    'The number of five-card hands possible from a standard',
	    f'''fifty-two card deck is: {combinations(52, 5)}\n''',
	)

	print(
	    'If a class of 40 students must be arranged into groups of',
	    f'''4 for group projects, there are {combinations(40, 4)} ways''',
	    'to arrange them.\n',
	)

	print(
	    'If 10 teams are competing in a Formula One race, there',
	    f'''are {combinations(10, 3)} ways that first, second and''',
	    'third place can be awarded.',
	)





from typing import Any, Dict, List, Optional, Tuple, Union

import torch
from torch import nn
from torch.utils.data import DistributedSampler, RandomSampler

from transformers import PreTrainedModel, Trainer, logging
from transformers.integrations import is_fairscale_available
from transformers.models.fsmt.configuration_fsmt import FSMTConfig
from transformers.optimization import (
    Adafactor,
    AdamW,
    get_constant_schedule,
    get_constant_schedule_with_warmup,
    get_cosine_schedule_with_warmup,
    get_cosine_with_hard_restarts_schedule_with_warmup,
    get_linear_schedule_with_warmup,
    get_polynomial_decay_schedule_with_warmup,
)
from transformers.trainer_pt_utils import get_tpu_sampler
from transformers.training_args import ParallelMode
from transformers.utils import is_torch_tpu_available


if is_fairscale_available():
						from fairscale.optim import OSS


__a  			=					logging.get_logger(__name__)

__a  			=					{
    'linear': get_linear_schedule_with_warmup,
    'cosine': get_cosine_schedule_with_warmup,
    'cosine_w_restarts': get_cosine_with_hard_restarts_schedule_with_warmup,
    'polynomial': get_polynomial_decay_schedule_with_warmup,
    'constant': get_constant_schedule,
    'constant_w_warmup': get_constant_schedule_with_warmup,
}
class  lowercase__(				UpperCAmelCase							):



	"""simple docstring"""




	def __init__(       self  :			Optional[Any]       ,							SCREAMING_SNAKE_CASE_  :			List[str]=None       ,							SCREAMING_SNAKE_CASE_  :			Optional[Any]=None       ,							*SCREAMING_SNAKE_CASE_  :			str       ,							**SCREAMING_SNAKE_CASE_  :			Optional[Any]       )       ->     List[str]:
					super().__init__(*SCREAMING_SNAKE_CASE_       ,							**SCREAMING_SNAKE_CASE_       )

					if config is None:
									assert isinstance(self.model       ,							SCREAMING_SNAKE_CASE_       ), (
									    "If no `config` is passed the model to be trained has to be of type `PreTrainedModel`, but is"
									    f''' {self.model.__class__}'''
									)
									lowercase_       =					self.model.config
					else:
									lowercase_       =					config

					lowercase_       =					data_args
					lowercase_       =					self.config.tgt_vocab_size if isinstance(self.config       ,							SCREAMING_SNAKE_CASE_       ) else self.config.vocab_size

					if self.args.label_smoothing != 0 or (self.data_args is not None and self.data_args.ignore_pad_token_for_loss):
									assert self.config.pad_token_id is not None, (
									    "Make sure that `config.pad_token_id` is correcly defined when ignoring `pad_token` for loss"
									    " calculation or doing label smoothing."
									)

					if self.config.pad_token_id is None and self.config.eos_token_id is not None:
									logger.warning(
									    f'''The `config.pad_token_id` is `None`. Using `config.eos_token_id` = {self.config.eos_token_id} for'''
									    ''' padding..'''       )

					if self.args.label_smoothing == 0:
									lowercase_       =					torch.nn.CrossEntropyLoss(ignore_index=self.config.pad_token_id       )
					else:
									# dynamically import label_smoothed_nll_loss
									from utils import label_smoothed_nll_loss

									lowercase_       =					label_smoothed_nll_loss
	def 						_lowercase  (       self  :			int       ,							SCREAMING_SNAKE_CASE_  :			int       )       ->     Optional[Any]:
					if self.optimizer is None:
									lowercase_       =					['''bias''', '''LayerNorm.weight''']
									lowercase_       =					[
									    {
									        '''params''': [p for n, p in self.model.named_parameters() if not any(nd in n for nd in no_decay       )],
									        '''weight_decay''': self.args.weight_decay,
									    },
									    {
									        '''params''': [p for n, p in self.model.named_parameters() if any(nd in n for nd in no_decay       )],
									        '''weight_decay''': 0.0,
									    },
									]
									lowercase_       =					Adafactor if self.args.adafactor else AdamW
									if self.args.adafactor:
													lowercase_       =					Adafactor
													lowercase_       =					{'''scale_parameter''': False, '''relative_step''': False}
									else:
													lowercase_       =					AdamW
													lowercase_       =					{
													    '''betas''': (self.args.adam_betaa, self.args.adam_betaa),
													    '''eps''': self.args.adam_epsilon,
													}
									lowercase_       =					self.args.learning_rate
									if self.sharded_ddp:
													lowercase_       =					OSS(
													    params=SCREAMING_SNAKE_CASE_       ,							optim=SCREAMING_SNAKE_CASE_       ,							**SCREAMING_SNAKE_CASE_       ,							)
									else:
													lowercase_       =					optimizer_cls(SCREAMING_SNAKE_CASE_       ,							**SCREAMING_SNAKE_CASE_       )

					if self.lr_scheduler is None:
									lowercase_       =					self._get_lr_scheduler(SCREAMING_SNAKE_CASE_       )
					else:  # ignoring --lr_scheduler
									logger.warning('''scheduler is passed to `Seq2SeqTrainer`, `--lr_scheduler` arg is ignored.'''       )
	def 						_lowercase  (       self  :			List[Any]       ,							SCREAMING_SNAKE_CASE_  :			Dict       )       ->     Dict:
					lowercase_       =					arg_to_scheduler[self.args.lr_scheduler]
					if self.args.lr_scheduler == "constant":
									lowercase_       =					schedule_func(self.optimizer       )
					elif self.args.lr_scheduler == "constant_w_warmup":
									lowercase_       =					schedule_func(self.optimizer       ,							num_warmup_steps=self.args.warmup_steps       )
					else:
									lowercase_       =					schedule_func(
									    self.optimizer       ,							num_warmup_steps=self.args.warmup_steps       ,							num_training_steps=SCREAMING_SNAKE_CASE_       )
					return scheduler
	def 						_lowercase  (       self  :			Tuple       )       ->     Optional[torch.utils.data.Sampler]:
					if isinstance(self.train_dataset       ,							torch.utils.data.IterableDataset       ):
									return None
					elif is_torch_tpu_available():
									return get_tpu_sampler(self.train_dataset       )
					else:
									if self.args.sortish_sampler:
													self.train_dataset.make_sortish_sampler(
													    self.args.per_device_train_batch_size       ,							distributed=(self.args.parallel_mode == ParallelMode.DISTRIBUTED)       ,							)

									return (
									    RandomSampler(self.train_dataset       )
									    if self.args.local_rank == -1
									    else DistributedSampler(self.train_dataset       )
									)
	def 						_lowercase  (       self  :			List[Any]       ,							SCREAMING_SNAKE_CASE_  :			int       ,							SCREAMING_SNAKE_CASE_  :			Dict       ,							SCREAMING_SNAKE_CASE_  :			List[Any]       )       ->     Any:
					if self.args.label_smoothing == 0:
									if self.data_args is not None and self.data_args.ignore_pad_token_for_loss:
													# force training to ignore pad token
													lowercase_       =					model(**SCREAMING_SNAKE_CASE_       ,							use_cache=SCREAMING_SNAKE_CASE_       )[0]
													lowercase_       =					self.loss_fn(logits.view(-1       ,							logits.shape[-1]       )       ,							labels.view(-1       )       )
									else:
													# compute usual loss via models
													lowercase_  ,	lowercase_       =					model(**SCREAMING_SNAKE_CASE_       ,							labels=SCREAMING_SNAKE_CASE_       ,							use_cache=SCREAMING_SNAKE_CASE_       )[:2]
					else:
									# compute label smoothed loss
									lowercase_       =					model(**SCREAMING_SNAKE_CASE_       ,							use_cache=SCREAMING_SNAKE_CASE_       )[0]
									lowercase_       =					torch.nn.functional.log_softmax(SCREAMING_SNAKE_CASE_       ,							dim=-1       )
									lowercase_  ,	lowercase_       =					self.loss_fn(SCREAMING_SNAKE_CASE_       ,							SCREAMING_SNAKE_CASE_       ,							self.args.label_smoothing       ,							ignore_index=self.config.pad_token_id       )
					return loss, logits
	def 						_lowercase  (       self  :			str       ,							SCREAMING_SNAKE_CASE_  :			Dict       ,							SCREAMING_SNAKE_CASE_  :			Optional[int]       )       ->     List[Any]:
					lowercase_       =					inputs.pop('''labels'''       )
					lowercase_  ,	lowercase_       =					self._compute_loss(SCREAMING_SNAKE_CASE_       ,							SCREAMING_SNAKE_CASE_       ,							SCREAMING_SNAKE_CASE_       )
					return loss
	def 						_lowercase  (       self  :			Optional[int]       ,							SCREAMING_SNAKE_CASE_  :			nn.Module       ,							SCREAMING_SNAKE_CASE_  :			Dict[str, Union[torch.Tensor, Any]]       ,							SCREAMING_SNAKE_CASE_  :			bool       ,							SCREAMING_SNAKE_CASE_  :			Optional[List[str]] = None       ,							)       ->     Tuple[Optional[float], Optional[torch.Tensor], Optional[torch.Tensor]]:
					lowercase_       =					self._prepare_inputs(SCREAMING_SNAKE_CASE_       )

					lowercase_       =					{
					    '''max_length''': self.data_args.val_max_target_length
					    if self.data_args is not None
					    else self.config.max_length,
					    '''num_beams''': self.data_args.eval_beams if self.data_args is not None else self.config.num_beams,
					}

					if self.args.predict_with_generate and not self.args.prediction_loss_only:
									lowercase_       =					self.model.generate(
									    inputs['''input_ids''']       ,							attention_mask=inputs['''attention_mask''']       ,							**SCREAMING_SNAKE_CASE_       ,							)
									# in case the batch is shorter than max length, the output should be padded
									if generated_tokens.shape[-1] < gen_kwargs["max_length"]:
													lowercase_       =					self._pad_tensors_to_max_len(SCREAMING_SNAKE_CASE_       ,							gen_kwargs['''max_length''']       )

					lowercase_       =					inputs.pop('''labels'''       )
					with torch.no_grad():
									# compute loss on predict data
									lowercase_  ,	lowercase_       =					self._compute_loss(SCREAMING_SNAKE_CASE_       ,							SCREAMING_SNAKE_CASE_       ,							SCREAMING_SNAKE_CASE_       )

					lowercase_       =					loss.mean().detach()
					if self.args.prediction_loss_only:
									return (loss, None, None)

					lowercase_       =					generated_tokens if self.args.predict_with_generate else logits

					if labels.shape[-1] < gen_kwargs["max_length"]:
									lowercase_       =					self._pad_tensors_to_max_len(SCREAMING_SNAKE_CASE_       ,							gen_kwargs['''max_length''']       )

					return (loss, logits, labels)




	def 						_lowercase  (       self  :			str       ,							SCREAMING_SNAKE_CASE_  :			Optional[Any]       ,							SCREAMING_SNAKE_CASE_  :			int       )       ->     Tuple:
					# If PAD token is not defined at least EOS token has to be defined
					lowercase_       =					self.config.pad_token_id if self.config.pad_token_id is not None else self.config.eos_token_id

					if pad_token_id is None:
									raise ValueError(
									    '''Make sure that either `config.pad_token_id` or `config.eos_token_id` is defined if tensor has to be'''
									    f''' padded to `max_length`={max_length}'''       )

					lowercase_       =					pad_token_id * torch.ones(
					    (tensor.shape[0], max_length)       ,							dtype=tensor.dtype       ,							device=tensor.device       )
					lowercase_       =					tensor
					return padded_tensor




