
import argparse
import glob
import logging
import os
import time
from argparse import Namespace

import numpy as np
import torch
from lightning_base import BaseTransformer, add_generic_args, generic_train
from torch.utils.data import DataLoader, TensorDataset

from transformers import glue_compute_metrics as compute_metrics
from transformers import glue_convert_examples_to_features as convert_examples_to_features
from transformers import glue_output_modes, glue_tasks_num_labels
from transformers import glue_processors as processors


__magic_name__            =  logging.getLogger(__name__)




class 					_SCREAMING_SNAKE_CASE  (      __UpperCamelCase ):
      _A						:		List[str]    	=     'sequence-classification'
      def __init__(			self		,	lowerCamelCase ):
          if type(lowerCamelCase ) == dict:
              snake_case__						=				Namespace(**lowerCamelCase )
          snake_case__						=				glue_output_modes[hparams.task]
          snake_case__						=				glue_tasks_num_labels[hparams.task]

          super().__init__(lowerCamelCase		,	lowerCamelCase		,	self.mode )
      def A_			(			self		,	**lowerCamelCase ):
          return self.model(**lowerCamelCase )
      def A_			(			self		,	lowerCamelCase		,	lowerCamelCase ):
          snake_case__						=				{"input_ids": batch[0], "attention_mask": batch[1], "labels": batch[3]}

          if self.config.model_type not in ["distilbert", "bart"]:
              snake_case__						=				batch[2] if self.config.model_type in ["bert", "xlnet", "albert"] else None

          snake_case__						=				self(**lowerCamelCase )
          snake_case__						=				outputs[0]

          snake_case__						=				self.trainer.lr_schedulers[0]["scheduler"]
          snake_case__						=				{"loss": loss, "rate": lr_scheduler.get_last_lr()[-1]}
          return {"loss": loss, "log": tensorboard_logs}
      def A_			(			self ):
          snake_case__						=				self.hparams
          snake_case__						=				processors[args.task]()
          snake_case__						=				processor.get_labels()

          for mode in ["train", "dev"]:
              snake_case__						=				self._feature_file(lowerCamelCase )
              if os.path.exists(lowerCamelCase ) and not args.overwrite_cache:
                  logger.info("Loading features from cached file %s"		,	lowerCamelCase )
              else:
                  logger.info("Creating features from dataset file at %s"		,	args.data_dir )
                  snake_case__						=				(
                      processor.get_dev_examples(args.data_dir )
                      if mode == "dev"
                      else processor.get_train_examples(args.data_dir )
                  )
                  snake_case__						=				convert_examples_to_features(
                      lowerCamelCase		,	self.tokenizer		,	max_length=args.max_seq_length		,	label_list=self.labels		,	output_mode=args.glue_output_mode		,	)
                  logger.info("Saving features into cached file %s"		,	lowerCamelCase )
                  torch.save(lowerCamelCase		,	lowerCamelCase )
      def A_			(			self		,	lowerCamelCase		,	lowerCamelCase		,	lowerCamelCase = False ):
          snake_case__						=				"dev" if mode == "test" else mode

          snake_case__						=				self._feature_file(lowerCamelCase )
          logger.info("Loading features from cached file %s"		,	lowerCamelCase )
          snake_case__						=				torch.load(lowerCamelCase )
          snake_case__						=				torch.tensor([f.input_ids for f in features]		,	dtype=torch.long )
          snake_case__						=				torch.tensor([f.attention_mask for f in features]		,	dtype=torch.long )
          snake_case__						=				torch.tensor([f.token_type_ids for f in features]		,	dtype=torch.long )
          if self.hparams.glue_output_mode == "classification":
              snake_case__						=				torch.tensor([f.label for f in features]		,	dtype=torch.long )
          elif self.hparams.glue_output_mode == "regression":
              snake_case__						=				torch.tensor([f.label for f in features]		,	dtype=torch.float )

          return DataLoader(
              TensorDataset(lowerCamelCase		,	lowerCamelCase		,	lowerCamelCase		,	lowerCamelCase )		,	batch_size=lowerCamelCase		,	shuffle=lowerCamelCase		,	)
      def A_			(			self		,	lowerCamelCase		,	lowerCamelCase ):
          snake_case__						=				{"input_ids": batch[0], "attention_mask": batch[1], "labels": batch[3]}

          if self.config.model_type not in ["distilbert", "bart"]:
              snake_case__						=				batch[2] if self.config.model_type in ["bert", "xlnet", "albert"] else None

          snake_case__						=				self(**lowerCamelCase )
          snake_case__						,					snake_case__						=				outputs[:2]
          snake_case__						=				logits.detach().cpu().numpy()
          snake_case__						=				inputs["labels"].detach().cpu().numpy()

          return {"val_loss": tmp_eval_loss.detach().cpu(), "pred": preds, "target": out_label_ids}
      def A_			(			self		,	lowerCamelCase ):
          snake_case__						=				torch.stack([x["val_loss"] for x in outputs] ).mean().detach().cpu().item()
          snake_case__						=				np.concatenate([x["pred"] for x in outputs]		,	axis=0 )

          if self.hparams.glue_output_mode == "classification":
              snake_case__						=				np.argmax(lowerCamelCase		,	axis=1 )
          elif self.hparams.glue_output_mode == "regression":
              snake_case__						=				np.squeeze(lowerCamelCase )

          snake_case__						=				np.concatenate([x["target"] for x in outputs]		,	axis=0 )
          snake_case__						=				[[] for _ in range(out_label_ids.shape[0] )]
          snake_case__						=				[[] for _ in range(out_label_ids.shape[0] )]

          snake_case__						=				{**{"val_loss": val_loss_mean}, **compute_metrics(self.hparams.task		,	lowerCamelCase		,	lowerCamelCase )}

          snake_case__						=				dict(results.items() )
          snake_case__						=				results
          return ret, preds_list, out_label_list
      def A_			(			self		,	lowerCamelCase ):
          snake_case__						,					snake_case__						,					snake_case__						=				self._eval_end(lowerCamelCase )
          snake_case__						=				ret["log"]
          return {"val_loss": logs["val_loss"], "log": logs, "progress_bar": logs}
      def A_			(			self		,	lowerCamelCase ):
          snake_case__						,					snake_case__						,					snake_case__						=				self._eval_end(lowerCamelCase )
          snake_case__						=				ret["log"]
          # `val_loss` is the key returned by `self._eval_end()` but actually refers to `test_loss`
          return {"avg_test_loss": logs["val_loss"], "log": logs, "progress_bar": logs}



      @staticmethod
      def A_			(			lowerCamelCase		,	lowerCamelCase ):
          BaseTransformer.add_model_specific_args(lowerCamelCase		,	lowerCamelCase )
          parser.add_argument(
              "--max_seq_length"		,	default=1_28		,	type=lowerCamelCase		,	help=(
                  "The maximum total input sequence length after tokenization. Sequences longer "
                  "than this will be truncated, sequences shorter will be padded."
              )		,	)

          parser.add_argument(
              "--task"		,	default=""		,	type=lowerCamelCase		,	required=lowerCamelCase		,	help="The GLUE task to run"		,	)
          parser.add_argument(
              "--gpus"		,	default=0		,	type=lowerCamelCase		,	help="The number of GPUs allocated for this, it is by default 0 meaning none"		,	)

          parser.add_argument(
              "--overwrite_cache"		,	action="store_true"		,	help="Overwrite the cached training and evaluation sets" )

          return parser





def 	SCREAMING_SNAKE_CASE__    (      ):
    snake_case__						=				argparse.ArgumentParser()
    add_generic_args(__lowerCAmelCase    ,		os.getcwd()							)
    snake_case__						=				GLUETransformer.add_model_specific_args(__lowerCAmelCase    ,		os.getcwd()							)
    snake_case__						=				parser.parse_args()

    # If output_dir not provided, a folder will be generated in pwd
    if args.output_dir is None:
        snake_case__						=				os.path.join(
            "./results"    ,		F"""{args.task}_{time.strftime("%Y%m%d_%H%M%S"							)}"""    ,		)
        os.makedirs(args.output_dir							)

    snake_case__						=				GLUETransformer(__lowerCAmelCase							)
    snake_case__						=				generic_train(__lowerCAmelCase    ,		__lowerCAmelCase							)

    # Optionally, predict on dev set and write to output_dir
    if args.do_predict:
        snake_case__						=				sorted(glob.glob(os.path.join(args.output_dir    ,		"checkpoint-epoch=*.ckpt"							)    ,		recursive=__lowerCAmelCase							)							)
        snake_case__						=				model.load_from_checkpoint(checkpoints[-1]							)
        return trainer.test(__lowerCAmelCase							)


if __name__ == "__main__":
     main()





from math import factorial





def 	SCREAMING_SNAKE_CASE__    (      __lowerCAmelCase = 100							):
    return sum(int(__lowerCAmelCase							) for x in str(factorial(__lowerCAmelCase							)							)							)


if __name__ == "__main__":
     print(solution(int(input('''Enter the Number: ''').strip())))



