
'''simple docstring'''







import numpy as np
import torch
from torch.utils.data import Dataset, IterableDataset

from ..utils.generic import ModelOutput


class 						__UpperCAmelCase      (					_lowerCamelCase						):


							def __init__(       self    ,   lowerCAmelCase_    ,   lowerCAmelCase_    ,   lowerCAmelCase_  ):





								"""simple docstring"""






								_snake_case   						=		dataset
								_snake_case   						=		process
								_snake_case   						=		params


							def __len__(       self  ):





								"""simple docstring"""






								return len(self.dataset  )




							def __getitem__(       self    ,   lowerCAmelCase_  ):





								"""simple docstring"""






								_snake_case   						=		self.dataset[i]
								_snake_case   						=		self.process(lowerCAmelCase_    ,   **self.params  )
								return processed


class 						__UpperCAmelCase      (					_lowerCamelCase						):


							def __init__(       self    ,   lowerCAmelCase_    ,   lowerCAmelCase_    ,   lowerCAmelCase_    ,   lowerCAmelCase_=None  ):





								"""simple docstring"""






								_snake_case   						=		loader
								_snake_case   						=		infer
								_snake_case   						=		params
								if loader_batch_size == 1:
									# Let's spare some time by deactivating altogether
									_snake_case   						=		None
								_snake_case   						=		loader_batch_size

								# Internal bookkeeping
								_snake_case   						=		None
								_snake_case   						=		None


							def __len__(       self  ):





								"""simple docstring"""






								return len(self.loader  )


							def __iter__(       self  ):





								"""simple docstring"""






								_snake_case   						=		iter(self.loader  )
								return self


							def  lowerCamelCase				(       self  ):





								"""simple docstring"""






								if isinstance(self._loader_batch_data    ,   torch.Tensor  ):
									# Batch data is simple tensor, just fetch the slice
									_snake_case   						=		self._loader_batch_data[self._loader_batch_index]
								else:
									# Batch data is assumed to be BaseModelOutput (or dict)
									_snake_case   						=		{}
									for k, element in self._loader_batch_data.items():
										if isinstance(lowerCAmelCase_    ,   lowerCAmelCase_  ):
											# Convert ModelOutput to tuple first
											_snake_case   						=		element.to_tuple()
											if isinstance(element[0]    ,   torch.Tensor  ):
												_snake_case   						=		tuple(el[self._loader_batch_index].unsqueeze(0  ) for el in element  )
											elif isinstance(element[0]    ,   np.ndarray  ):
												_snake_case   						=		tuple(np.expand_dims(el[self._loader_batch_index]    ,   0  ) for el in element  )
											continue
										if k in {"hidden_states", "past_key_values", "attentions"} and isinstance(lowerCAmelCase_    ,   lowerCAmelCase_  ):
											# Those are stored as lists of tensors so need specific unbatching.
											if isinstance(element[0]    ,   torch.Tensor  ):
												_snake_case   						=		tuple(el[self._loader_batch_index].unsqueeze(0  ) for el in element  )
											elif isinstance(element[0]    ,   np.ndarray  ):
												_snake_case   						=		tuple(np.expand_dims(el[self._loader_batch_index]    ,   0  ) for el in element  )
											continue
										if element is None:
											# This can happen for optional data that get passed around
											_snake_case   						=		None
										elif isinstance(element[self._loader_batch_index]    ,   torch.Tensor  ):
											# Take correct batch data, but make it looked like batch_size=1
											# For compatibility with other methods within transformers

											_snake_case   						=		element[self._loader_batch_index].unsqueeze(0  )
										elif isinstance(element[self._loader_batch_index]    ,   np.ndarray  ):
											# Take correct batch data, but make it looked like batch_size=1
											# For compatibility with other methods within transformers
											_snake_case   						=		np.expand_dims(element[self._loader_batch_index]    ,   0  )
										else:
											# This is typically a list, so no need to `unsqueeze`.
											_snake_case   						=		element[self._loader_batch_index]
            # Recreate the element by reusing the original class to make it look
            # batch_size=1
									_snake_case   						=		self._loader_batch_data.__class__(lowerCAmelCase_  )
								self._loader_batch_index += 1
								return result




							def  lowerCamelCase				(       self  ):





								"""simple docstring"""






								if self._loader_batch_index is not None and self._loader_batch_index < self.loader_batch_size:
									# We are currently unrolling a batch so we just need to return
									# the current item within a batch
									return self.loader_batch_item()

								# We're out of items within a batch
								_snake_case   						=		next(self.iterator  )
								_snake_case   						=		self.infer(lowerCAmelCase_    ,   **self.params  )
								# We now have a batch of "inferred things".
								if self.loader_batch_size is not None:
									# Try to infer the size of the batch
									if isinstance(lowerCAmelCase_    ,   torch.Tensor  ):
										_snake_case   						=		processed
									else:
										_snake_case   						=		list(processed.keys()  )[0]
										_snake_case   						=		processed[key]
									if isinstance(lowerCAmelCase_    ,   lowerCAmelCase_  ):
										_snake_case   						=		len(lowerCAmelCase_  )
									else:
										_snake_case   						=		first_tensor.shape[0]
									if 0 < observed_batch_size < self.loader_batch_size:
										# could be last batch so we can't unroll as many
										# elements.
										_snake_case   						=		observed_batch_size
									# Setting internal index to unwrap the batch
									_snake_case   						=		processed
									_snake_case   						=		0
									return self.loader_batch_item()
								else:
									# We're not unrolling batches
									return processed


class 						__UpperCAmelCase      (					_lowerCamelCase						):


							def __init__(       self    ,   lowerCAmelCase_    ,   lowerCAmelCase_    ,   lowerCAmelCase_    ,   lowerCAmelCase_=None  ):





								"""simple docstring"""






								super().__init__(lowerCAmelCase_    ,   lowerCAmelCase_    ,   lowerCAmelCase_  )


							def __iter__(       self  ):





								"""simple docstring"""






								_snake_case   						=		iter(self.loader  )
								_snake_case   						=		None
								return self




							def  lowerCamelCase				(       self  ):





								"""simple docstring"""






								if self.subiterator is None:
									_snake_case   						=		self.infer(next(self.iterator  )    ,   **self.params  )
								try:
									# Try to return next item
									_snake_case   						=		next(self.subiterator  )
								except StopIteration:
									# When a preprocess iterator ends, we can start lookig at the next item
									# ChunkIterator will keep feeding until ALL elements of iterator
									# all have created their subiterator and have been iterating against.
									#
									# Another way to look at it, is we're basically flattening lists of lists
									# into a single list, but with generators
									_snake_case   						=		self.infer(next(self.iterator  )    ,   **self.params  )
									_snake_case   						=		next(self.subiterator  )
								return processed


class 						__UpperCAmelCase      (					_lowerCamelCase						):


							def __iter__(       self  ):





								"""simple docstring"""






								_snake_case   						=		iter(self.loader  )
								return self




							def  lowerCamelCase				(       self  ):





								"""simple docstring"""






								_snake_case   						=		False
								_snake_case   						=		[]
								if self._loader_batch_index is not None and self._loader_batch_index < self.loader_batch_size:
									while self._loader_batch_index < self.loader_batch_size:
										_snake_case   						=		self.loader_batch_item()
										_snake_case   						=		item.pop('is_last'  )
										accumulator.append(lowerCAmelCase_  )
										if is_last:
											return accumulator

								while not is_last:
									_snake_case   						=		self.infer(next(self.iterator  )    ,   **self.params  )
									if self.loader_batch_size is not None:
										if isinstance(lowerCAmelCase_    ,   torch.Tensor  ):
											_snake_case   						=		processed
										else:
											_snake_case   						=		list(processed.keys()  )[0]
											_snake_case   						=		processed[key]
										if isinstance(lowerCAmelCase_    ,   lowerCAmelCase_  ):
											_snake_case   						=		len(lowerCAmelCase_  )
										else:
											_snake_case   						=		first_tensor.shape[0]
										if 0 < observed_batch_size < self.loader_batch_size:
											# could be last batch so we can't unroll as many
											# elements.
											_snake_case   						=		observed_batch_size
										_snake_case   						=		processed
										_snake_case   						=		0
										while self._loader_batch_index < self.loader_batch_size:
											_snake_case   						=		self.loader_batch_item()
											_snake_case   						=		item.pop('is_last'  )
											accumulator.append(lowerCAmelCase_  )
											if is_last:
												return accumulator
									else:
										_snake_case   						=		processed
										_snake_case   						=		item.pop('is_last'  )
										accumulator.append(lowerCAmelCase_  )
								return accumulator


class 						__UpperCAmelCase      (					_lowerCamelCase						):


							def __init__(       self    ,   lowerCAmelCase_    ,   lowerCAmelCase_  ):





								"""simple docstring"""






								_snake_case   						=		dataset
								_snake_case   						=		key


							def __len__(       self  ):





								"""simple docstring"""






								return len(self.dataset  )




							def __getitem__(       self    ,   lowerCAmelCase_  ):





								"""simple docstring"""






								return self.dataset[i][self.key]


class 						__UpperCAmelCase      (					_lowerCamelCase						):


							def __init__(       self    ,   lowerCAmelCase_    ,   lowerCAmelCase_    ,   lowerCAmelCase_  ):





								"""simple docstring"""






								_snake_case   						=		dataset
								_snake_case   						=		keya
								_snake_case   						=		keya


							def __len__(       self  ):





								"""simple docstring"""






								return len(self.dataset  )




							def __getitem__(       self    ,   lowerCAmelCase_  ):





								"""simple docstring"""






								return {"text": self.dataset[i][self.keya], "text_pair": self.dataset[i][self.keya]}









"""simple docstring"""



def 						_SCREAMING_SNAKE_CASE (    __snake_case			:  int    ):





  '''simple docstring'''





  return sum(i for i in range(1		,					number // 2 + 1    ) if number % i == 0    ) == number


if __name__ == "__main__":
    print('Program to check whether a number is a Perfect number or not...')
    _UpperCamelCase		:  Tuple						=		int(input('Enter number: ').strip())
    print(F'''{number} is {'' if perfect(number) else 'not '}a Perfect Number.''')


