

# Lint as: python3
import os
import re
import urllib.parse
from pathlib import Path
from typing import Callable, List, Optional, Union
from zipfile import ZipFile

from ..utils.file_utils import cached_path, hf_github_url
from ..utils.logging import get_logger
from ..utils.version import Version


a_							=      get_logger(__name__)


class 			UpperCAmelCase__    :



  """simple docstring"""






  lowerCAmelCase__		:	Dict    		= 'dummy_data'
  lowerCAmelCase__		:	int    		= 'datasets'
  lowerCAmelCase__		:	Any    		= False






  def __init__(				self:			Optional[int]				,				__lowerCAmelCase:			str				,				__lowerCAmelCase:			str				,				__lowerCAmelCase:			Union[Version, str]				,				__lowerCAmelCase:			Optional[str] = None				,				__lowerCAmelCase:			bool = False				,				__lowerCAmelCase:			bool = True				,				__lowerCAmelCase:			Optional[List[Callable]] = None				,				) -> int:




    '''simple docstring'''




    __UpperCAmelCase						    =       0
    __UpperCAmelCase						    =       dataset_name
    __UpperCAmelCase						    =       cache_dir
    __UpperCAmelCase						    =       use_local_dummy_data
    __UpperCAmelCase						    =       config
    # download_callbacks take a single url as input
    __UpperCAmelCase						    =       download_callbacks or []
    # if False, it doesn't load existing files and it returns the paths of the dummy files relative
    # to the dummy_data zip file root
    __UpperCAmelCase						    =       load_existing_dummy_data

    # TODO(PVP, QL) might need to make this more general
    __UpperCAmelCase						    =       str(__A   )
    # to be downloaded
    __UpperCAmelCase						    =       None
    __UpperCAmelCase						    =       None






  @property
  def 	_UpperCAmelCase				(				self:			str   ) -> Any:




    '''simple docstring'''




    if self._dummy_file is None:
      __UpperCAmelCase						    =       self.download_dummy_data()
    return self._dummy_file






  @property
  def 	_UpperCAmelCase				(				self:			Any   ) -> Dict:




    '''simple docstring'''




    if self.config is not None:
      # structure is dummy / config_name / version_name
      return os.path.join("dummy"				,				self.config.name				,				self.version_name   )
    # structure is dummy / version_name
    return os.path.join("dummy"				,				self.version_name   )






  @property
  def 	_UpperCAmelCase				(				self:			Optional[Any]   ) -> str:




    '''simple docstring'''




    return os.path.join(self.dummy_data_folder				,				"dummy_data.zip"   )






  def 	_UpperCAmelCase				(				self:			List[Any]   ) -> Dict:




    '''simple docstring'''




    __UpperCAmelCase						    =       (
        self.local_path_to_dummy_data if self.use_local_dummy_data is True else self.github_path_to_dummy_data
    )

    __UpperCAmelCase						    =       cached_path(
        __A				,				cache_dir=self.cache_dir				,				extract_compressed_file=__A				,				force_extract=__A   )

    return os.path.join(__A				,				self.dummy_file_name   )






  @property
  def 	_UpperCAmelCase				(				self:			str   ) -> List[str]:




    '''simple docstring'''




    return os.path.join(self.datasets_scripts_dir				,				self.dataset_name				,				self.dummy_zip_file   )






  @property
  def 	_UpperCAmelCase				(				self:			List[str]   ) -> Dict:




    '''simple docstring'''




    if self._bucket_url is None:
      __UpperCAmelCase						    =       hf_github_url(self.dataset_name				,				self.dummy_zip_file.replace(os.sep				,				"/"   )   )
    return self._bucket_url






  @property
  def 	_UpperCAmelCase				(				self:			List[str]   ) -> Optional[Any]:




    '''simple docstring'''




    if os.path.isdir(self.dummy_file   ):
      return self.dummy_file
    # else cut off path to file -> example `xsum`.
    return "/".join(self.dummy_file.replace(os.sep				,				"/"   ).split("/"   )[:-1]   )






  def 	_UpperCAmelCase				(				self:			Union[str, Any]				,				__lowerCAmelCase:			Optional[Any]				,				*__lowerCAmelCase:			Optional[int]   ) -> Tuple:




    '''simple docstring'''




    if self.load_existing_dummy_data:
      # dummy data is downloaded and tested
      __UpperCAmelCase						    =       self.dummy_file
    else:
      # dummy data cannot be downloaded and only the path to dummy file is returned
      __UpperCAmelCase						    =       self.dummy_file_name

    # special case when data_url is a dict
    if isinstance(__A				,				__A   ):
      return self.create_dummy_data_dict(__A				,				__A   )
    elif isinstance(__A				,				(list, tuple)   ):
      return self.create_dummy_data_list(__A				,				__A   )
    else:
      return self.create_dummy_data_single(__A				,				__A   )






  def 	_UpperCAmelCase				(				self:			Union[str, Any]				,				__lowerCAmelCase:			List[str]				,				*__lowerCAmelCase:			List[Any]   ) -> Optional[Any]:




    '''simple docstring'''




    return self.download_and_extract(__A   )






  def 	_UpperCAmelCase				(				self:			Any				,				__lowerCAmelCase:			Union[str, Any]				,				__lowerCAmelCase:			str   ) -> Tuple:




    '''simple docstring'''




    return self.download_and_extract(__A   )






  def 	_UpperCAmelCase				(				self:			Union[str, Any]				,				__lowerCAmelCase:			int				,				*__lowerCAmelCase:			List[str]				,				**__lowerCAmelCase:			str   ) -> int:




    '''simple docstring'''




    return path






  def 	_UpperCAmelCase				(				self:			Optional[Any]   ) -> Dict:




    '''simple docstring'''




    return {}






  def 	_UpperCAmelCase				(				self:			Dict				,				__lowerCAmelCase:			int				,				__lowerCAmelCase:			Tuple   ) -> Any:




    '''simple docstring'''




    __UpperCAmelCase						    =       {}
    for key, single_urls in data_url.items():
      for download_callback in self.download_callbacks:
        if isinstance(__A				,				__A   ):
          for single_url in single_urls:
            download_callback(__A   )
        else:
          __UpperCAmelCase						    =       single_urls
          download_callback(__A   )
            # we force the name of each key to be the last file / folder name of the url path
            # if the url has arguments, we need to encode them with urllib.parse.quote_plus
      if isinstance(__A				,				__A   ):
        __UpperCAmelCase						    =       [os.path.join(__A				,				urllib.parse.quote_plus(Path(__A   ).name   )   ) for x in single_urls]
      else:
        __UpperCAmelCase						    =       single_urls
        __UpperCAmelCase						    =       os.path.join(__A				,				urllib.parse.quote_plus(Path(__A   ).name   )   )
      __UpperCAmelCase						    =       value

    # make sure that values are unique
    if all(isinstance(__A				,				__A   ) for i in dummy_data_dict.values()   ) and len(set(dummy_data_dict.values()   )   ) < len(
        dummy_data_dict.values()   ):
      # append key to value to make its name unique
      __UpperCAmelCase						    =       {key: value + key for key, value in dummy_data_dict.items()}

    return dummy_data_dict






  def 	_UpperCAmelCase				(				self:			List[Any]				,				__lowerCAmelCase:			Optional[Any]				,				__lowerCAmelCase:			Union[str, Any]   ) -> Optional[Any]:




    '''simple docstring'''




    __UpperCAmelCase						    =       []
    # trick: if there are many shards named like `data.txt-000001-of-00300`, only use the first one
    __UpperCAmelCase						    =       all(bool(re.findall("[0-9]{3,}-of-[0-9]{3,}"				,				__A   )   ) for url in data_url   )
    __UpperCAmelCase						    =       all(
        url.startswith("https://ftp.ncbi.nlm.nih.gov/pubmed/baseline/pubmed"   ) for url in data_url   )
    if data_url and (is_tf_records or is_pubmed_records):
      __UpperCAmelCase						    =       [data_url[0]] * len(__A   )
    for single_url in data_url:
      for download_callback in self.download_callbacks:
        download_callback(__A   )
      # we force the name of each key to be the last file / folder name of the url path
      # if the url has arguments, we need to encode them with urllib.parse.quote_plus
      __UpperCAmelCase						    =       os.path.join(__A				,				urllib.parse.quote_plus(single_url.split("/"   )[-1]   )   )
      dummy_data_list.append(__A   )
    return dummy_data_list






  def 	_UpperCAmelCase				(				self:			Optional[int]				,				__lowerCAmelCase:			List[Any]				,				__lowerCAmelCase:			Any   ) -> str:




    '''simple docstring'''




    for download_callback in self.download_callbacks:
      download_callback(__A   )
    # we force the name of each key to be the last file / folder name of the url path
    # if the url has arguments, we need to encode them with urllib.parse.quote_plus
    __UpperCAmelCase						    =       os.path.join(__A				,				urllib.parse.quote_plus(data_url.split("/"   )[-1]   )   )
    if os.path.exists(__A   ) or not self.load_existing_dummy_data:
      return value
    else:
      # Backward compatibility, maybe deprecate at one point.
      # For many datasets with single url calls to dl_manager.download_and_extract,
      # the dummy_data.zip file is actually the zipped downloaded file
      # while now we expected the dummy_data.zip file to be a directory containing
      # the downloaded file.
      return path_to_dummy_data






  def 	_UpperCAmelCase				(				self:			List[str]   ) -> Union[str, Any]:




    '''simple docstring'''




    pass






  def 	_UpperCAmelCase				(				self:			Dict   ) -> List[Any]:




    '''simple docstring'''




    pass






  def 	_UpperCAmelCase				(				self:			Any				,				__lowerCAmelCase:			Any   ) -> List[str]:




    '''simple docstring'''




    def _iter_archive_members(__lowerCAmelCase:			Tuple   ):
      # this preserves the order of the members inside the ZIP archive
      __UpperCAmelCase						    =       Path(self.dummy_file   ).parent
      __UpperCAmelCase						    =       path.relative_to(__A   )
      with ZipFile(self.local_path_to_dummy_data   ) as zip_file:
        __UpperCAmelCase						    =       zip_file.namelist()
      for member in members:
        if member.startswith(relative_path.as_posix()   ):
          yield dummy_parent_path.joinpath(__A   )

    __UpperCAmelCase						    =       Path(__A   )
    __UpperCAmelCase						    =       _iter_archive_members(__A   ) if self.use_local_dummy_data else path.rglob("*"   )
    for file_path in file_paths:
      if file_path.is_file() and not file_path.name.startswith((".", "__")   ):
        yield file_path.relative_to(__A   ).as_posix(), file_path.open("rb"   )






  def 	_UpperCAmelCase				(				self:			int				,				__lowerCAmelCase:			Any   ) -> Union[str, Any]:




    '''simple docstring'''




    if not isinstance(__A				,				__A   ):
      __UpperCAmelCase						    =       [paths]
    for path in paths:
      if os.path.isfile(__A   ):
        if os.path.basename(__A   ).startswith((".", "__")   ):
          return
        yield path
      else:
        for dirpath, dirnames, filenames in os.walk(__A   ):
          if os.path.basename(__A   ).startswith((".", "__")   ):
            continue
          dirnames.sort()
          for filename in sorted(__A   ):
            if filename.startswith((".", "__")   ):
              continue
            yield os.path.join(__A				,				__A   )




from sklearn.metrics import fa_score

import datasets


a_							=      """
The F1 score is the harmonic mean of the precision and recall. It can be computed with the equation:
F1 = 2 * (precision * recall) / (precision + recall)
"""


a_							=      """
Args:
    predictions (`list` of `int`): Predicted labels.
    references (`list` of `int`): Ground truth labels.
    labels (`list` of `int`): The set of labels to include when `average` is not set to `'binary'`, and the order of the labels if `average` is `None`. Labels present in the data can be excluded, for example to calculate a multiclass average ignoring a majority negative class. Labels not present in the data will result in 0 components in a macro average. For multilabel targets, labels are column indices. By default, all labels in `predictions` and `references` are used in sorted order. Defaults to None.
    pos_label (`int`): The class to be considered the positive class, in the case where `average` is set to `binary`. Defaults to 1.
    average (`string`): This parameter is required for multiclass/multilabel targets. If set to `None`, the scores for each class are returned. Otherwise, this determines the type of averaging performed on the data. Defaults to `'binary'`.

        - 'binary': Only report results for the class specified by `pos_label`. This is applicable only if the classes found in `predictions` and `references` are binary.
        - 'micro': Calculate metrics globally by counting the total true positives, false negatives and false positives.
        - 'macro': Calculate metrics for each label, and find their unweighted mean. This does not take label imbalance into account.
        - 'weighted': Calculate metrics for each label, and find their average weighted by support (the number of true instances for each label). This alters `'macro'` to account for label imbalance. This option can result in an F-score that is not between precision and recall.
        - 'samples': Calculate metrics for each instance, and find their average (only meaningful for multilabel classification).
    sample_weight (`list` of `float`): Sample weights Defaults to None.

Returns:
    f1 (`float` or `array` of `float`): F1 score or list of f1 scores, depending on the value passed to `average`. Minimum possible value is 0. Maximum possible value is 1. Higher f1 scores are better.

Examples:

    Example 1-A simple binary example
        >>> f1_metric = datasets.load_metric(\"f1\")
        >>> results = f1_metric.compute(references=[0, 1, 0, 1, 0], predictions=[0, 0, 1, 1, 0])
        >>> print(results)
        {'f1': 0.5}

    Example 2-The same simple binary example as in Example 1, but with `pos_label` set to `0`.
        >>> f1_metric = datasets.load_metric(\"f1\")
        >>> results = f1_metric.compute(references=[0, 1, 0, 1, 0], predictions=[0, 0, 1, 1, 0], pos_label=0)
        >>> print(round(results['f1'], 2))
        0.67

    Example 3-The same simple binary example as in Example 1, but with `sample_weight` included.
        >>> f1_metric = datasets.load_metric(\"f1\")
        >>> results = f1_metric.compute(references=[0, 1, 0, 1, 0], predictions=[0, 0, 1, 1, 0], sample_weight=[0.9, 0.5, 3.9, 1.2, 0.3])
        >>> print(round(results['f1'], 2))
        0.35

    Example 4-A multiclass example, with different values for the `average` input.
        >>> predictions = [0, 2, 1, 0, 0, 1]
        >>> references = [0, 1, 2, 0, 1, 2]
        >>> results = f1_metric.compute(predictions=predictions, references=references, average=\"macro\")
        >>> print(round(results['f1'], 2))
        0.27
        >>> results = f1_metric.compute(predictions=predictions, references=references, average=\"micro\")
        >>> print(round(results['f1'], 2))
        0.33
        >>> results = f1_metric.compute(predictions=predictions, references=references, average=\"weighted\")
        >>> print(round(results['f1'], 2))
        0.27
        >>> results = f1_metric.compute(predictions=predictions, references=references, average=None)
        >>> print(results)
        {'f1': array([0.8, 0. , 0. ])}
"""


a_							=      """
@article{scikit-learn,
    title={Scikit-learn: Machine Learning in {P}ython},
    author={Pedregosa, F. and Varoquaux, G. and Gramfort, A. and Michel, V.
           and Thirion, B. and Grisel, O. and Blondel, M. and Prettenhofer, P.
           and Weiss, R. and Dubourg, V. and Vanderplas, J. and Passos, A. and
           Cournapeau, D. and Brucher, M. and Perrot, M. and Duchesnay, E.},
    journal={Journal of Machine Learning Research},
    volume={12},
    pages={2825--2830},
    year={2011}
}
"""


@datasets.utils.file_utils.add_start_docstrings(_DESCRIPTION		,	_KWARGS_DESCRIPTION					)
class 			UpperCAmelCase__    (		datasets.Metric					):



  """simple docstring"""






  def 	_UpperCAmelCase				(				self:			int   ) -> Dict:




    '''simple docstring'''




    return datasets.MetricInfo(
        description=_DESCRIPTION				,				citation=_CITATION				,				inputs_description=_KWARGS_DESCRIPTION				,				features=datasets.Features(
            {
                "predictions": datasets.Sequence(datasets.Value("int32"   )   ),
                "references": datasets.Sequence(datasets.Value("int32"   )   ),
            }
            if self.config_name == "multilabel"
            else {
                "predictions": datasets.Value("int32"   ),
                "references": datasets.Value("int32"   ),
            }   )				,				reference_urls=["https://scikit-learn.org/stable/modules/generated/sklearn.metrics.f1_score.html"]				,				)






  def 	_UpperCAmelCase				(				self:			Any				,				__lowerCAmelCase:			Tuple				,				__lowerCAmelCase:			Any				,				__lowerCAmelCase:			List[Any]=None				,				__lowerCAmelCase:			Optional[Any]=1				,				__lowerCAmelCase:			List[Any]="binary"				,				__lowerCAmelCase:			List[Any]=None   ) -> Optional[int]:




    '''simple docstring'''




    __UpperCAmelCase						    =       fa_score(
        __lowerCAmelCase				,				__lowerCAmelCase				,				labels=__lowerCAmelCase				,				pos_label=__lowerCAmelCase				,				average=__lowerCAmelCase				,				sample_weight=__lowerCAmelCase   )
    return {"f1": float(__lowerCAmelCase   ) if score.size == 1 else score}



