



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

import numpy as np

from ...audio_utils import mel_filter_bank, spectrogram, window_function
from ...feature_extraction_sequence_utils import SequenceFeatureExtractor
from ...feature_extraction_utils import BatchFeature
from ...utils import TensorType, logging


lowerCAmelCase__					  =  logging.get_logger(__name__)

class 				snake_case__(_UpperCamelCase      ):

					"""simple docstring"""






					lowercase_								=		["""input_features"""]







					def __init__(							self :     str				,       SCREAMING_SNAKE_CASE :     Tuple=80				,       SCREAMING_SNAKE_CASE :     Optional[int]=16_000				,       SCREAMING_SNAKE_CASE :     Optional[int]=160				,       SCREAMING_SNAKE_CASE :     str=30				,       SCREAMING_SNAKE_CASE :     List[Any]=400				,       SCREAMING_SNAKE_CASE :     str=0.0				,       SCREAMING_SNAKE_CASE :     int=False				,       **SCREAMING_SNAKE_CASE :     Union[str, Any]				,       ):
									super().__init__(
									    feature_size=SCREAMING_SNAKE_CASE				,       sampling_rate=SCREAMING_SNAKE_CASE				,       padding_value=SCREAMING_SNAKE_CASE				,       return_attention_mask=SCREAMING_SNAKE_CASE				,       **SCREAMING_SNAKE_CASE				,       )
									lowercase__					:   Union[str, Any]													=					n_fft
									lowercase__					:   Optional[Any]													=					hop_length
									lowercase__					:   Union[str, Any]													=					chunk_length
									lowercase__					:   Any													=					chunk_length * sampling_rate
									lowercase__					:   Optional[Any]													=					self.n_samples // hop_length
									lowercase__					:   Any													=					sampling_rate
									lowercase__					:   List[str]													=					mel_filter_bank(
									    num_frequency_bins=1 + n_fft // 2				,       num_mel_filters=SCREAMING_SNAKE_CASE				,       min_frequency=0.0				,       max_frequency=8_000.0				,       sampling_rate=SCREAMING_SNAKE_CASE				,       norm="slaney"				,       mel_scale="slaney"				,       )







					def 			snake_case					(							self :     int				,       SCREAMING_SNAKE_CASE :     np.array					):
									lowercase__					:   Any													=					spectrogram(
									    SCREAMING_SNAKE_CASE				,       window_function(self.n_fft				,       "hann"					)				,       frame_length=self.n_fft				,       hop_length=self.hop_length				,       power=2.0				,       mel_filters=self.mel_filters				,       log_mel="log10"				,       )
									lowercase__					:   Optional[int]													=					log_spec[:, :-1]
									lowercase__					:   List[Any]													=					np.maximum(SCREAMING_SNAKE_CASE				,       log_spec.max() - 8.0					)
									lowercase__					:   Tuple													=					(log_spec + 4.0) / 4.0
									return log_spec







					@staticmethod
					# Copied from transformers.models.wav2vec2.feature_extraction_wav2vec2.Wav2Vec2FeatureExtractor.zero_mean_unit_var_norm
					def 			snake_case					(							SCREAMING_SNAKE_CASE :     List[np.ndarray]				,       SCREAMING_SNAKE_CASE :     List[np.ndarray]				,       SCREAMING_SNAKE_CASE :     float = 0.0					):
									if attention_mask is not None:
													lowercase__					:   Union[str, Any]													=					np.array(SCREAMING_SNAKE_CASE				,       np.intaa					)
													lowercase__					:   Optional[int]													=					[]

													for vector, length in zip(SCREAMING_SNAKE_CASE				,       attention_mask.sum(-1					)					):
																	lowercase__					:   int													=					(vector - vector[:length].mean()) / np.sqrt(vector[:length].var() + 1E-7					)
																	if length < normed_slice.shape[0]:
																					lowercase__					:   str													=					padding_value

																	normed_input_values.append(SCREAMING_SNAKE_CASE					)
									else:
													lowercase__					:   int													=					[(x - x.mean()) / np.sqrt(x.var() + 1E-7					) for x in input_values]

									return normed_input_values







					def __call__(							self :     List[str]				,       SCREAMING_SNAKE_CASE :     Union[np.ndarray, List[float], List[np.ndarray], List[List[float]]]				,       SCREAMING_SNAKE_CASE :     bool = True				,       SCREAMING_SNAKE_CASE :     Optional[int] = None				,       SCREAMING_SNAKE_CASE :     Optional[Union[str, TensorType]] = None				,       SCREAMING_SNAKE_CASE :     Optional[bool] = None				,       SCREAMING_SNAKE_CASE :     Optional[str] = "max_length"				,       SCREAMING_SNAKE_CASE :     Optional[int] = None				,       SCREAMING_SNAKE_CASE :     Optional[int] = None				,       SCREAMING_SNAKE_CASE :     Optional[bool] = None				,       **SCREAMING_SNAKE_CASE :     Optional[int]				,       ):

									if sampling_rate is not None:
													if sampling_rate != self.sampling_rate:
																	raise ValueError(
																	    f"""The model corresponding to this feature extractor: {self.__class__.__name__} was trained using a"""
																	    f""" sampling rate of {self.sampling_rate}. Please make sure that the provided `raw_speech` input"""
																	    f""" was sampled with {self.sampling_rate} and not {sampling_rate}."""					)
									else:
													logger.warning(
													    "It is strongly recommended to pass the `sampling_rate` argument to this function. "
													    "Failing to do so can result in silent errors that might be hard to debug."					)

									lowercase__					:   Optional[Any]													=					isinstance(SCREAMING_SNAKE_CASE				,       np.ndarray					) and len(raw_speech.shape					) > 1
									if is_batched_numpy and len(raw_speech.shape					) > 2:
													raise ValueError(f"""Only mono-channel audio is supported for input to {self}"""					)
									lowercase__					:   List[str]													=					is_batched_numpy or (
									    isinstance(SCREAMING_SNAKE_CASE				,       (list, tuple)					) and (isinstance(raw_speech[0]				,       (np.ndarray, tuple, list)					))
									)

									if is_batched:
													lowercase__					:   str													=					[np.asarray([speech]				,       dtype=np.floataa					).T for speech in raw_speech]
									elif not is_batched and not isinstance(SCREAMING_SNAKE_CASE				,       np.ndarray					):
													lowercase__					:   Union[str, Any]													=					np.asarray(SCREAMING_SNAKE_CASE				,       dtype=np.floataa					)
									elif isinstance(SCREAMING_SNAKE_CASE				,       np.ndarray					) and raw_speech.dtype is np.dtype(np.floataa					):
													lowercase__					:   Optional[Any]													=					raw_speech.astype(np.floataa					)

									# always return batch
									if not is_batched:
													lowercase__					:   Union[str, Any]													=					[np.asarray([raw_speech]					).T]

									lowercase__					:   str													=					BatchFeature({"input_features": raw_speech}					)

									# convert into correct format for padding

									lowercase__					:   Union[str, Any]													=					self.pad(
									    SCREAMING_SNAKE_CASE				,       padding=SCREAMING_SNAKE_CASE				,       max_length=max_length if max_length else self.n_samples				,       truncation=SCREAMING_SNAKE_CASE				,       pad_to_multiple_of=SCREAMING_SNAKE_CASE				,       return_attention_mask=return_attention_mask or do_normalize				,       )

									# zero-mean and unit-variance normalization
									if do_normalize:
													lowercase__					:   List[str]													=					self.zero_mean_unit_var_norm(
													    padded_inputs["input_features"]				,       attention_mask=padded_inputs["attention_mask"]				,       padding_value=self.padding_value				,       )
													lowercase__					:   Optional[Any]													=					np.stack(padded_inputs["input_features"]				,       axis=0					)

									# make sure list is in array format
									lowercase__					:   Optional[Any]													=					padded_inputs.get("input_features"					).transpose(2				,       0				,       1					)

									lowercase__					:   Any													=					[self._np_extract_fbank_features(SCREAMING_SNAKE_CASE					) for waveform in input_features[0]]

									if isinstance(input_features[0]				,       SCREAMING_SNAKE_CASE					):
													lowercase__					:   str													=					[np.asarray(SCREAMING_SNAKE_CASE				,       dtype=np.floataa					) for feature in input_features]
									else:
													lowercase__					:   Optional[int]													=					input_features

									if return_attention_mask:
													# rescale from sample (48000) to feature (3000)
													lowercase__					:   Union[str, Any]													=					padded_inputs["attention_mask"][:, :: self.hop_length]

									if return_tensors is not None:
													lowercase__					:   Union[str, Any]													=					padded_inputs.convert_to_tensors(SCREAMING_SNAKE_CASE					)

									return padded_inputs







					def 			snake_case					(							self :     Tuple					):
									lowercase__					:   str													=					copy.deepcopy(self.__dict__					)
									lowercase__					:   Dict													=					self.__class__.__name__
									if "mel_filters" in output:
													del output["mel_filters"]
									return output









from collections import Counter
from timeit import timeit


def  __lowerCamelCase (       lowerCamelCase__ = ""					,			):

				"""simple docstring"""


				return sum(c % 2 for c in Counter(input_str.replace(" "					,			""						).lower()						).values()						) < 2


def  __lowerCamelCase (       lowerCamelCase__ = ""						):

				"""simple docstring"""


				if len(lowerCamelCase__						) == 0:
								return True
				lowercase__					:   str													=					input_str.replace(" "					,			""						).lower()
				# character_freq_dict: Stores the frequency of every character in the input string
				lowercase__					:   dict[str, int]													=					{}

				for character in lower_case_input_str:
								lowercase__					:   List[Any]													=					character_freq_dict.get(lowerCamelCase__					,			0						) + 1
				lowercase__					:   List[Any]													=					0

				for character_count in character_freq_dict.values():
								if character_count % 2:
												odd_char += 1
				if odd_char > 1:
								return False
				return True


def  __lowerCamelCase (       lowerCamelCase__ = ""						):

				"""simple docstring"""


				print("\nFor string = "					,			lowerCamelCase__					,			":"						)
				print(
				    "> can_string_be_rearranged_as_palindrome_counter()"					,			"\tans ="					,			can_string_be_rearranged_as_palindrome_counter(lowerCamelCase__						)					,			"\ttime ="					,			timeit(
				        "z.can_string_be_rearranged_as_palindrome_counter(z.check_str)"					,			setup="import __main__ as z"					,			)					,			"seconds"					,			)
				print(
				    "> can_string_be_rearranged_as_palindrome()"					,			"\tans ="					,			can_string_be_rearranged_as_palindrome(lowerCamelCase__						)					,			"\ttime ="					,			timeit(
				        "z.can_string_be_rearranged_as_palindrome(z.check_str)"					,			setup="import __main__ as z"					,			)					,			"seconds"					,			)


if __name__ == "__main__":
				lowerCAmelCase__					  =  input(
				    '''Enter string to determine if it can be rearranged as a palindrome or not: '''
				).strip()
				benchmark(check_str)
				lowerCAmelCase__					  =  can_string_be_rearranged_as_palindrome_counter(check_str)
				print(f'''{check_str} can {"" if status else "not "}be rearranged as a palindrome''')




