


import os
from itertools import chain
from random import randrange, shuffle

import pytest

from .sola import PokerHand

a_						:       Tuple      			=				(
    """4S 3H 2C 7S 5H""",
    """9D 8H 2C 6S 7H""",
    """2D 6D 9D TH 7D""",
    """TC 8C 2S JH 6C""",
    """JH 8S TH AH QH""",
    """TS KS 5S 9S AC""",
    """KD 6S 9D TH AD""",
    """KS 8D 4D 9S 4S""",  # pair
    """8C 4S KH JS 4D""",  # pair
    """QH 8H KD JH 8S""",  # pair
    """KC 4H KS 2H 8D""",  # pair
    """KD 4S KC 3H 8S""",  # pair
    """AH 8S AS KC JH""",  # pair
    """3H 4C 4H 3S 2H""",  # 2 pairs
    """5S 5D 2C KH KH""",  # 2 pairs
    """3C KH 5D 5S KH""",  # 2 pairs
    """AS 3C KH AD KH""",  # 2 pairs
    """7C 7S 3S 7H 5S""",  # 3 of a kind
    """7C 7S KH 2H 7H""",  # 3 of a kind
    """AC KH QH AH AS""",  # 3 of a kind
    """2H 4D 3C AS 5S""",  # straight (low ace)
    """3C 5C 4C 2C 6H""",  # straight
    """6S 8S 7S 5H 9H""",  # straight
    """JS QS 9H TS KH""",  # straight
    """QC KH TS JS AH""",  # straight (high ace)
    """8C 9C 5C 3C TC""",  # flush
    """3S 8S 9S 5S KS""",  # flush
    """4C 5C 9C 8C KC""",  # flush
    """JH 8H AH KH QH""",  # flush
    """3D 2H 3H 2C 2D""",  # full house
    """2H 2C 3S 3H 3D""",  # full house
    """KH KC 3S 3H 3D""",  # full house
    """JC 6H JS JD JH""",  # 4 of a kind
    """JC 7H JS JD JH""",  # 4 of a kind
    """JC KH JS JD JH""",  # 4 of a kind
    """2S AS 4S 5S 3S""",  # straight flush (low ace)
    """2D 6D 3D 4D 5D""",  # straight flush
    """5C 6C 3C 7C 4C""",  # straight flush
    """JH 9H TH KH QH""",  # straight flush
    """JH AH TH KH QH""",  # royal flush (high ace straight flush)
)

a_						:       Optional[int]      			=				(
    ("""2H 3H 4H 5H 6H""", """KS AS TS QS JS""", """Loss"""),
    ("""2H 3H 4H 5H 6H""", """AS AD AC AH JD""", """Win"""),
    ("""AS AH 2H AD AC""", """JS JD JC JH 3D""", """Win"""),
    ("""2S AH 2H AS AC""", """JS JD JC JH AD""", """Loss"""),
    ("""2S AH 2H AS AC""", """2H 3H 5H 6H 7H""", """Win"""),
    ("""AS 3S 4S 8S 2S""", """2H 3H 5H 6H 7H""", """Win"""),
    ("""2H 3H 5H 6H 7H""", """2S 3H 4H 5S 6C""", """Win"""),
    ("""2S 3H 4H 5S 6C""", """3D 4C 5H 6H 2S""", """Tie"""),
    ("""2S 3H 4H 5S 6C""", """AH AC 5H 6H AS""", """Win"""),
    ("""2S 2H 4H 5S 4C""", """AH AC 5H 6H AS""", """Loss"""),
    ("""2S 2H 4H 5S 4C""", """AH AC 5H 6H 7S""", """Win"""),
    ("""6S AD 7H 4S AS""", """AH AC 5H 6H 7S""", """Loss"""),
    ("""2S AH 4H 5S KC""", """AH AC 5H 6H 7S""", """Loss"""),
    ("""2S 3H 6H 7S 9C""", """7H 3C TH 6H 9S""", """Loss"""),
    ("""4S 5H 6H TS AC""", """3S 5H 6H TS AC""", """Win"""),
    ("""2S AH 4H 5S 6C""", """AD 4C 5H 6H 2C""", """Tie"""),
    ("""AS AH 3H AD AC""", """AS AH 2H AD AC""", """Win"""),
    ("""AH AC 5H 5C QS""", """AH AC 5H 5C KS""", """Loss"""),
    ("""AH AC 5H 5C QS""", """KH KC 5H 5C QS""", """Win"""),
    ("""7C 7S KH 2H 7H""", """3C 3S AH 2H 3H""", """Win"""),
    ("""3C 3S AH 2H 3H""", """7C 7S KH 2H 7H""", """Loss"""),
    ("""6H 5H 4H 3H 2H""", """5H 4H 3H 2H AH""", """Win"""),
    ("""5H 4H 3H 2H AH""", """5H 4H 3H 2H AH""", """Tie"""),
    ("""5H 4H 3H 2H AH""", """6H 5H 4H 3H 2H""", """Loss"""),
    ("""AH AD KS KC AC""", """AH KD KH AC KC""", """Win"""),
    ("""2H 4D 3C AS 5S""", """2H 4D 3C 6S 5S""", """Loss"""),
    ("""2H 3S 3C 3H 2S""", """3S 3C 2S 2H 2D""", """Win"""),
    ("""4D 6D 5D 2D JH""", """3S 8S 3H TC KH""", """Loss"""),
    ("""4S 6C 8S 3S 7S""", """AD KS 2D 7D 7C""", """Loss"""),
    ("""6S 4C 7H 8C 3H""", """5H JC AH 9D 9C""", """Loss"""),
    ("""9D 9H JH TC QH""", """3C 2S JS 5C 7H""", """Win"""),
    ("""2H TC 8S AD 9S""", """4H TS 7H 2C 5C""", """Win"""),
    ("""9D 3S 2C 7S 7C""", """JC TD 3C TC 9H""", """Loss"""),
)

a_						:       Any      			=				(
    ("""2H 3H 4H 5H 6H""", True),
    ("""AS AH 2H AD AC""", False),
    ("""2H 3H 5H 6H 7H""", True),
    ("""KS AS TS QS JS""", True),
    ("""8H 9H QS JS TH""", False),
    ("""AS 3S 4S 8S 2S""", True),
)

a_						:       Union[str, Any]      			=				(
    ("""2H 3H 4H 5H 6H""", True),
    ("""AS AH 2H AD AC""", False),
    ("""2H 3H 5H 6H 7H""", False),
    ("""KS AS TS QS JS""", True),
    ("""8H 9H QS JS TH""", True),
)

a_						:       Any      			=				(
    ("""2H 4D 3C AS 5S""", True, [5, 4, 3, 2, 14]),
    ("""2H 5D 3C AS 5S""", False, [14, 5, 5, 3, 2]),
    ("""JH QD KC AS TS""", False, [14, 13, 12, 11, 10]),
    ("""9D 3S 2C 7S 7C""", False, [9, 7, 7, 3, 2]),
)

a_						:       Dict      			=				(
    ("""JH AH TH KH QH""", 0),
    ("""JH 9H TH KH QH""", 0),
    ("""JC KH JS JD JH""", 7),
    ("""KH KC 3S 3H 3D""", 6),
    ("""8C 9C 5C 3C TC""", 0),
    ("""JS QS 9H TS KH""", 0),
    ("""7C 7S KH 2H 7H""", 3),
    ("""3C KH 5D 5S KH""", 2),
    ("""QH 8H KD JH 8S""", 1),
    ("""2D 6D 9D TH 7D""", 0),
)

a_						:       str      			=				(
    ("""JH AH TH KH QH""", 23),
    ("""JH 9H TH KH QH""", 22),
    ("""JC KH JS JD JH""", 21),
    ("""KH KC 3S 3H 3D""", 20),
    ("""8C 9C 5C 3C TC""", 19),
    ("""JS QS 9H TS KH""", 18),
    ("""7C 7S KH 2H 7H""", 17),
    ("""3C KH 5D 5S KH""", 16),
    ("""QH 8H KD JH 8S""", 15),
    ("""2D 6D 9D TH 7D""", 14),
)





def __snake_case      (   ):
 lowerCamelCase_				,lowerCamelCase_  				=						randrange(len(UpperCAmelCase_	)	), randrange(len(UpperCAmelCase_	)	)
 lowerCamelCase_  				=						["Loss", "Tie", "Win"][(play >= oppo) + (play > oppo)]
 lowerCamelCase_				,lowerCamelCase_  				=						SORTED_HANDS[play], SORTED_HANDS[oppo]
 return hand, other, expected





def __snake_case      (   UpperCAmelCase_		:		int = 100	):
 return (generate_random_hand() for _ in range(UpperCAmelCase_	))





@pytest.mark.parametrize("hand, expected"      ,       UpperCAmelCase_	)
def __snake_case      (   UpperCAmelCase_		:		int      ,       UpperCAmelCase_		:		Any	):
 assert PokerHand(UpperCAmelCase_	)._is_flush() == expected





@pytest.mark.parametrize("hand, expected"      ,       UpperCAmelCase_	)
def __snake_case      (   UpperCAmelCase_		:		Dict      ,       UpperCAmelCase_		:		Optional[Any]	):
 assert PokerHand(UpperCAmelCase_	)._is_straight() == expected





@pytest.mark.parametrize("hand, expected, card_values"      ,       UpperCAmelCase_	)
def __snake_case      (   UpperCAmelCase_		:		str      ,       UpperCAmelCase_		:		List[str]      ,       UpperCAmelCase_		:		List[Any]	):
 lowerCamelCase_  				=						PokerHand(UpperCAmelCase_	)
 assert player._is_five_high_straight() == expected
 assert player._card_values == card_values





@pytest.mark.parametrize("hand, expected"      ,       UpperCAmelCase_	)
def __snake_case      (   UpperCAmelCase_		:		Tuple      ,       UpperCAmelCase_		:		Union[str, Any]	):
 assert PokerHand(UpperCAmelCase_	)._is_same_kind() == expected





@pytest.mark.parametrize("hand, expected"      ,       UpperCAmelCase_	)
def __snake_case      (   UpperCAmelCase_		:		Optional[Any]      ,       UpperCAmelCase_		:		List[Any]	):
 assert PokerHand(UpperCAmelCase_	)._hand_type == expected





@pytest.mark.parametrize("hand, other, expected"      ,       UpperCAmelCase_	)
def __snake_case      (   UpperCAmelCase_		:		Any      ,       UpperCAmelCase_		:		int      ,       UpperCAmelCase_		:		str	):
 assert PokerHand(UpperCAmelCase_	).compare_with(PokerHand(UpperCAmelCase_	)	) == expected





@pytest.mark.parametrize("hand, other, expected"      ,       generate_random_hands()	)
def __snake_case      (   UpperCAmelCase_		:		Tuple      ,       UpperCAmelCase_		:		Union[str, Any]      ,       UpperCAmelCase_		:		Any	):
 assert PokerHand(UpperCAmelCase_	).compare_with(PokerHand(UpperCAmelCase_	)	) == expected





def __snake_case      (   ):
 lowerCamelCase_  				=						[PokerHand(UpperCAmelCase_	) for hand in SORTED_HANDS]
 lowerCamelCase_  				=						poker_hands.copy()
 shuffle(UpperCAmelCase_	)
 lowerCamelCase_  				=						chain(sorted(UpperCAmelCase_	)	)
 for index, hand in enumerate(UpperCAmelCase_	):
  assert hand == poker_hands[index]





def __snake_case      (   ):
 # Test that five high straights are compared correctly.
 lowerCamelCase_  				=						[PokerHand("2D AC 3H 4H 5S"	), PokerHand("2S 3H 4H 5S 6C"	)]
 pokerhands.sort(reverse=UpperCAmelCase_	)
 assert pokerhands[0].__str__() == "2S 3H 4H 5S 6C"





def __snake_case      (   ):
 # Multiple calls to five_high_straight function should still return True
 # and shouldn't mutate the list in every call other than the first.
 lowerCamelCase_  				=						PokerHand("2C 4S AS 3D 5C"	)
 lowerCamelCase_  				=						True
 lowerCamelCase_  				=						[5, 4, 3, 2, 14]
 for _ in range(10	):
  assert pokerhand._is_five_high_straight() == expected
  assert pokerhand._card_values == expected_card_values







def __snake_case      (   ):
 # Problem number 54 from Project Euler
 # Testing from poker_hands.txt file
 lowerCamelCase_  				=						0
 lowerCamelCase_  				=						os.path.abspath(os.path.dirname(UpperCAmelCase_	)	)
 lowerCamelCase_  				=						os.path.join(UpperCAmelCase_      ,       "poker_hands.txt"	)
 with open(UpperCAmelCase_	) as file_hand:
  for line in file_hand:
   lowerCamelCase_  				=						line[:14].strip()
   lowerCamelCase_  				=						line[15:].strip()
   lowerCamelCase_				,lowerCamelCase_  				=						PokerHand(UpperCAmelCase_	), PokerHand(UpperCAmelCase_	)
   lowerCamelCase_  				=						player.compare_with(UpperCAmelCase_	)
   if output == "Win":
    answer += 1
 assert answer == 376







'''simple docstring'''

# 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_						:       Dict      			=				get_logger(__name__)





class   snake_case					:





  """simple docstring"""




  _lowerCamelCase						=						"dummy_data"
  _lowerCamelCase						=						"datasets"
  _lowerCamelCase						=						False






  def __init__(					self    ,						UpperCamelCase    ,						UpperCamelCase    ,						UpperCamelCase    ,						UpperCamelCase = None    ,						UpperCamelCase = False    ,						UpperCamelCase = True    ,						UpperCamelCase = None    ,						):







   """simple docstring"""
   lowerCamelCase_  				=						0
   lowerCamelCase_  				=						dataset_name
   lowerCamelCase_  				=						cache_dir
   lowerCamelCase_  				=						use_local_dummy_data
   lowerCamelCase_  				=						config
   # download_callbacks take a single url as input
   lowerCamelCase_  				=						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
   lowerCamelCase_  				=						load_existing_dummy_data

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






  @property
  def 						snake_case	(					self  ):







   """simple docstring"""
   if self._dummy_file is None:
    lowerCamelCase_  				=						self.download_dummy_data()
   return self._dummy_file






  @property
  def 						snake_case	(					self  ):







   """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 						snake_case	(					self  ):







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






  def 						snake_case	(					self  ):







   """simple docstring"""
   lowerCamelCase_  				=						(
       self.local_path_to_dummy_data if self.use_local_dummy_data is True else self.github_path_to_dummy_data
   )

   lowerCamelCase_  				=						cached_path(
       UpperCamelCase    ,						cache_dir=self.cache_dir    ,						extract_compressed_file=UpperCamelCase    ,						force_extract=UpperCamelCase  )

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






  @property
  def 						snake_case	(					self  ):







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






  @property
  def 						snake_case	(					self  ):







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






  @property
  def 						snake_case	(					self  ):







   """simple docstring"""
   # return full path if its a dir
   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 						snake_case	(					self    ,						UpperCamelCase    ,						*UpperCamelCase  ):







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

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






  def 						snake_case	(					self    ,						UpperCamelCase    ,						*UpperCamelCase  ):







   """simple docstring"""
   return self.download_and_extract(UpperCamelCase  )






  def 						snake_case	(					self    ,						UpperCamelCase    ,						UpperCamelCase  ):







   """simple docstring"""
   return self.download_and_extract(UpperCamelCase  )






  def 						snake_case	(					self    ,						UpperCamelCase    ,						*UpperCamelCase    ,						**UpperCamelCase  ):







   """simple docstring"""
   return path






  def 						snake_case	(					self  ):







   """simple docstring"""
   return {}






  def 						snake_case	(					self    ,						UpperCamelCase    ,						UpperCamelCase  ):







   """simple docstring"""
   lowerCamelCase_  				=						{}
   for key, single_urls in data_url.items():
    for download_callback in self.download_callbacks:
     if isinstance(UpperCamelCase    ,						UpperCamelCase  ):
      for single_url in single_urls:
       download_callback(UpperCamelCase  )
     else:
      lowerCamelCase_  				=						single_urls
      download_callback(UpperCamelCase  )
            # 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(UpperCamelCase    ,						UpperCamelCase  ):
     lowerCamelCase_  				=						[os.path.join(UpperCamelCase    ,						urllib.parse.quote_plus(Path(UpperCamelCase  ).name  )  ) for x in single_urls]
    else:
     lowerCamelCase_  				=						single_urls
     lowerCamelCase_  				=						os.path.join(UpperCamelCase    ,						urllib.parse.quote_plus(Path(UpperCamelCase  ).name  )  )
    lowerCamelCase_  				=						value

   # make sure that values are unique
   if all(isinstance(UpperCamelCase    ,						UpperCamelCase  ) 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
    lowerCamelCase_  				=						{key: value + key for key, value in dummy_data_dict.items()}

   return dummy_data_dict






  def 						snake_case	(					self    ,						UpperCamelCase    ,						UpperCamelCase  ):







   """simple docstring"""
   lowerCamelCase_  				=						[]
   # trick: if there are many shards named like `data.txt-000001-of-00300`, only use the first one
   lowerCamelCase_  				=						all(bool(re.findall("[0-9]{3,}-of-[0-9]{3,}"    ,						UpperCamelCase  )  ) for url in data_url  )
   lowerCamelCase_  				=						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):
    lowerCamelCase_  				=						[data_url[0]] * len(UpperCamelCase  )
   for single_url in data_url:
    for download_callback in self.download_callbacks:
     download_callback(UpperCamelCase  )
    # 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
    lowerCamelCase_  				=						os.path.join(UpperCamelCase    ,						urllib.parse.quote_plus(single_url.split("/"  )[-1]  )  )
    dummy_data_list.append(UpperCamelCase  )
   return dummy_data_list






  def 						snake_case	(					self    ,						UpperCamelCase    ,						UpperCamelCase  ):







   """simple docstring"""
   for download_callback in self.download_callbacks:
    download_callback(UpperCamelCase  )
   # 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
   lowerCamelCase_  				=						os.path.join(UpperCamelCase    ,						urllib.parse.quote_plus(data_url.split("/"  )[-1]  )  )
   if os.path.exists(UpperCamelCase  ) 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 						snake_case	(					self  ):







   """simple docstring"""
   pass






  def 						snake_case	(					self  ):







   """simple docstring"""
   pass






  def 						snake_case	(					self    ,						UpperCamelCase  ):







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

   lowerCamelCase_  				=						Path(UpperCamelCase  )
   lowerCamelCase_  				=						_iter_archive_members(UpperCamelCase  ) 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(UpperCamelCase  ).as_posix(), file_path.open("rb"  )







  def 						snake_case	(					self    ,						UpperCamelCase  ):







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



