


"""simple docstring"""



import argparse
import json

import gdown
import numpy as np
import torch
from huggingface_hub import hf_hub_download

from transformers import (
    VideoMAEConfig,
    VideoMAEForPreTraining,
    VideoMAEForVideoClassification,
    VideoMAEImageProcessor,
)
def      UpperCAmelCase     (       _lowercase :   str	)						-> Optional[Any]:


	"""simple docstring"""




	lowerCAmelCase_      							=			VideoMAEConfig()

	set_architecture_configs(_lowercase			,   _lowercase	)

	if "finetuned" not in model_name:
		lowerCAmelCase_      							=			False

	if "finetuned" in model_name:
		lowerCAmelCase_      							=			'''huggingface/label-files'''
		if "kinetics" in model_name:
			lowerCAmelCase_      							=			4_0_0
			lowerCAmelCase_      							=			'''kinetics400-id2label.json'''
		elif "ssv2" in model_name:
			lowerCAmelCase_      							=			1_7_4
			lowerCAmelCase_      							=			'''something-something-v2-id2label.json'''
		else:
			raise ValueError('''Model name should either contain \'kinetics\' or \'ssv2\' in case it\'s fine-tuned.'''	)
		lowerCAmelCase_      							=			json.load(open(hf_hub_download(_lowercase			,   _lowercase			,   repo_type='''dataset'''	)			,   '''r'''	)	)
		lowerCAmelCase_      							=			{int(_lowercase	): v for k, v in idalabel.items()}
		lowerCAmelCase_      							=			idalabel
		lowerCAmelCase_      							=			{v: k for k, v in idalabel.items()}

	return config
def      UpperCAmelCase     (       _lowercase :   str			,   _lowercase :   int	)						-> Dict:


	"""simple docstring"""




	if "small" in model_name:
		lowerCAmelCase_      							=			3_8_4
		lowerCAmelCase_      							=			1_5_3_6
		lowerCAmelCase_      							=			1_2
		lowerCAmelCase_      							=			1_6
		lowerCAmelCase_      							=			1_2
		lowerCAmelCase_      							=			3
		lowerCAmelCase_      							=			1_9_2
		lowerCAmelCase_      							=			7_6_8
	elif "large" in model_name:
		lowerCAmelCase_      							=			1_0_2_4
		lowerCAmelCase_      							=			4_0_9_6
		lowerCAmelCase_      							=			2_4
		lowerCAmelCase_      							=			1_6
		lowerCAmelCase_      							=			1_2
		lowerCAmelCase_      							=			8
		lowerCAmelCase_      							=			5_1_2
		lowerCAmelCase_      							=			2_0_4_8
	elif "huge" in model_name:
		lowerCAmelCase_      							=			1_2_8_0
		lowerCAmelCase_      							=			5_1_2_0
		lowerCAmelCase_      							=			3_2
		lowerCAmelCase_      							=			1_6
		lowerCAmelCase_      							=			1_2
		lowerCAmelCase_      							=			8
		lowerCAmelCase_      							=			6_4_0
		lowerCAmelCase_      							=			2_5_6_0
	elif "base" not in model_name:
		raise ValueError('''Model name should include either "small", "base", "large", or "huge"'''	)
def      UpperCAmelCase     (       _lowercase :   Optional[Any]	)						-> Any:


	"""simple docstring"""




	if "encoder." in name:
		lowerCAmelCase_      							=			name.replace('''encoder.'''			,   ''''''	)
	if "cls_token" in name:
		lowerCAmelCase_      							=			name.replace('''cls_token'''			,   '''videomae.embeddings.cls_token'''	)
	if "decoder_pos_embed" in name:
		lowerCAmelCase_      							=			name.replace('''decoder_pos_embed'''			,   '''decoder.decoder_pos_embed'''	)
	if "pos_embed" in name and "decoder" not in name:
		lowerCAmelCase_      							=			name.replace('''pos_embed'''			,   '''videomae.embeddings.position_embeddings'''	)
	if "patch_embed.proj" in name:
		lowerCAmelCase_      							=			name.replace('''patch_embed.proj'''			,   '''videomae.embeddings.patch_embeddings.projection'''	)
	if "patch_embed.norm" in name:
		lowerCAmelCase_      							=			name.replace('''patch_embed.norm'''			,   '''videomae.embeddings.norm'''	)
	if "decoder.blocks" in name:
		lowerCAmelCase_      							=			name.replace('''decoder.blocks'''			,   '''decoder.decoder_layers'''	)
	if "blocks" in name:
		lowerCAmelCase_      							=			name.replace('''blocks'''			,   '''videomae.encoder.layer'''	)
	if "attn.proj" in name:
		lowerCAmelCase_      							=			name.replace('''attn.proj'''			,   '''attention.output.dense'''	)
	if "attn" in name and "bias" not in name:
		lowerCAmelCase_      							=			name.replace('''attn'''			,   '''attention.self'''	)
	if "attn" in name:
		lowerCAmelCase_      							=			name.replace('''attn'''			,   '''attention.attention'''	)
	if "norm1" in name:
		lowerCAmelCase_      							=			name.replace('''norm1'''			,   '''layernorm_before'''	)
	if "norm2" in name:
		lowerCAmelCase_      							=			name.replace('''norm2'''			,   '''layernorm_after'''	)
	if "mlp.fc1" in name:
		lowerCAmelCase_      							=			name.replace('''mlp.fc1'''			,   '''intermediate.dense'''	)
	if "mlp.fc2" in name:
		lowerCAmelCase_      							=			name.replace('''mlp.fc2'''			,   '''output.dense'''	)
	if "decoder_embed" in name:
		lowerCAmelCase_      							=			name.replace('''decoder_embed'''			,   '''decoder.decoder_embed'''	)
	if "decoder_norm" in name:
		lowerCAmelCase_      							=			name.replace('''decoder_norm'''			,   '''decoder.decoder_norm'''	)
	if "decoder_pred" in name:
		lowerCAmelCase_      							=			name.replace('''decoder_pred'''			,   '''decoder.decoder_pred'''	)
	if "norm.weight" in name and "decoder" not in name and "fc" not in name:
		lowerCAmelCase_      							=			name.replace('''norm.weight'''			,   '''videomae.layernorm.weight'''	)
	if "norm.bias" in name and "decoder" not in name and "fc" not in name:
		lowerCAmelCase_      							=			name.replace('''norm.bias'''			,   '''videomae.layernorm.bias'''	)
	if "head" in name and "decoder" not in name:
		lowerCAmelCase_      							=			name.replace('''head'''			,   '''classifier'''	)

	return name
def      UpperCAmelCase     (       _lowercase :   int			,   _lowercase :   str	)						-> str:


	"""simple docstring"""




	for key in orig_state_dict.copy().keys():
		lowerCAmelCase_      							=			orig_state_dict.pop(_lowercase	)

		if key.startswith('''encoder.'''	):
			lowerCAmelCase_      							=			key.replace('''encoder.'''			,   ''''''	)

		if "qkv" in key:
			lowerCAmelCase_      							=			key.split('''.'''	)
			if key.startswith('''decoder.blocks'''	):
				lowerCAmelCase_      							=			config.decoder_hidden_size
				lowerCAmelCase_      							=			int(key_split[2]	)
				lowerCAmelCase_      							=			'''decoder.decoder_layers.'''
				if "weight" in key:
					lowerCAmelCase_      							=			val[:dim, :]
					lowerCAmelCase_      							=			val[dim : dim * 2, :]
					lowerCAmelCase_      							=			val[-dim:, :]
			else:
				lowerCAmelCase_      							=			config.hidden_size
				lowerCAmelCase_      							=			int(key_split[1]	)
				lowerCAmelCase_      							=			'''videomae.encoder.layer.'''
				if "weight" in key:
					lowerCAmelCase_      							=			val[:dim, :]
					lowerCAmelCase_      							=			val[dim : dim * 2, :]
					lowerCAmelCase_      							=			val[-dim:, :]
		else:
			lowerCAmelCase_      							=			val

	return orig_state_dict
def      UpperCAmelCase     (       )						-> str:


	"""simple docstring"""




	lowerCAmelCase_      							=			hf_hub_download(
	    repo_id='''hf-internal-testing/spaghetti-video'''			,   filename='''eating_spaghetti.npy'''			,   repo_type='''dataset'''	)
	lowerCAmelCase_      							=			np.load(_lowercase	)
	return list(_lowercase	)
def      UpperCAmelCase     (       _lowercase :   Any			,   _lowercase :   Optional[Any]			,   _lowercase :   Optional[int]			,   _lowercase :   List[str]	)						-> str:


	"""simple docstring"""




	lowerCAmelCase_      							=			get_videomae_config(_lowercase	)

	if "finetuned" in model_name:
		lowerCAmelCase_      							=			VideoMAEForVideoClassification(_lowercase	)
	else:
		lowerCAmelCase_      							=			VideoMAEForPreTraining(_lowercase	)

	# download original checkpoint, hosted on Google Drive
	lowerCAmelCase_      							=			'''pytorch_model.bin'''
	gdown.cached_download(_lowercase			,   _lowercase			,   quiet=_lowercase	)
	lowerCAmelCase_      							=			torch.load(_lowercase			,   map_location='''cpu'''	)
	if "model" in files:
		lowerCAmelCase_      							=			files['''model''']
	else:
		lowerCAmelCase_      							=			files['''module''']
	lowerCAmelCase_      							=			convert_state_dict(_lowercase			,   _lowercase	)

	model.load_state_dict(_lowercase	)
	model.eval()

	# verify model on basic input
	lowerCAmelCase_      							=			VideoMAEImageProcessor(image_mean=[0.5, 0.5, 0.5]			,   image_std=[0.5, 0.5, 0.5]	)
	lowerCAmelCase_      							=			prepare_video()
	lowerCAmelCase_      							=			image_processor(_lowercase			,   return_tensors='''pt'''	)

	if "finetuned" not in model_name:
		lowerCAmelCase_      							=			hf_hub_download(repo_id='''hf-internal-testing/bool-masked-pos'''			,   filename='''bool_masked_pos.pt'''	)
		lowerCAmelCase_      							=			torch.load(_lowercase	)

	lowerCAmelCase_      							=			model(**_lowercase	)
	lowerCAmelCase_      							=			outputs.logits

	lowerCAmelCase_      							=			[
	    '''videomae-small-finetuned-kinetics''',
	    '''videomae-small-finetuned-ssv2''',
	    # Kinetics-400 checkpoints (short = pretrained only for 800 epochs instead of 1600)
	    '''videomae-base-short''',
	    '''videomae-base-short-finetuned-kinetics''',
	    '''videomae-base''',
	    '''videomae-base-finetuned-kinetics''',
	    '''videomae-large''',
	    '''videomae-large-finetuned-kinetics''',
	    '''videomae-huge-finetuned-kinetics''',
	    # Something-Something-v2 checkpoints (short = pretrained only for 800 epochs instead of 2400)
	    '''videomae-base-short-ssv2''',
	    '''videomae-base-short-finetuned-ssv2''',
	    '''videomae-base-ssv2''',
	    '''videomae-base-finetuned-ssv2''',
	]

	# NOTE: logits were tested with image_mean and image_std equal to [0.5, 0.5, 0.5] and [0.5, 0.5, 0.5]
	if model_name == "videomae-small-finetuned-kinetics":
		lowerCAmelCase_      							=			torch.Size([1, 4_0_0]	)
		lowerCAmelCase_      							=			torch.tensor([-0.9_2_9_1, -0.4_0_6_1, -0.9_3_0_7]	)
	elif model_name == "videomae-small-finetuned-ssv2":
		lowerCAmelCase_      							=			torch.Size([1, 1_7_4]	)
		lowerCAmelCase_      							=			torch.tensor([0.2_6_7_1, -0.4_6_8_9, -0.8_2_3_5]	)
	elif model_name == "videomae-base":
		lowerCAmelCase_      							=			torch.Size([1, 1_4_0_8, 1_5_3_6]	)
		lowerCAmelCase_      							=			torch.tensor([[0.7_7_3_9, 0.7_9_6_8, 0.7_0_8_9], [0.6_7_0_1, 0.7_4_8_7, 0.6_2_0_9], [0.4_2_8_7, 0.5_1_5_8, 0.4_7_7_3]]	)
	elif model_name == "videomae-base-short":
		lowerCAmelCase_      							=			torch.Size([1, 1_4_0_8, 1_5_3_6]	)
		lowerCAmelCase_      							=			torch.tensor([[0.7_9_9_4, 0.9_6_1_2, 0.8_5_0_8], [0.7_4_0_1, 0.8_9_5_8, 0.8_3_0_2], [0.5_8_6_2, 0.7_4_6_8, 0.7_3_2_5]]	)
		# we verified the loss both for normalized and unnormalized targets for this one
		lowerCAmelCase_      							=			torch.tensor([0.5_1_4_2]	) if config.norm_pix_loss else torch.tensor([0.6_4_6_9]	)
	elif model_name == "videomae-large":
		lowerCAmelCase_      							=			torch.Size([1, 1_4_0_8, 1_5_3_6]	)
		lowerCAmelCase_      							=			torch.tensor([[0.7_1_4_9, 0.7_9_9_7, 0.6_9_6_6], [0.6_7_6_8, 0.7_8_6_9, 0.6_9_4_8], [0.5_1_3_9, 0.6_2_2_1, 0.5_6_0_5]]	)
	elif model_name == "videomae-large-finetuned-kinetics":
		lowerCAmelCase_      							=			torch.Size([1, 4_0_0]	)
		lowerCAmelCase_      							=			torch.tensor([0.0_7_7_1, 0.0_0_1_1, -0.3_6_2_5]	)
	elif model_name == "videomae-huge-finetuned-kinetics":
		lowerCAmelCase_      							=			torch.Size([1, 4_0_0]	)
		lowerCAmelCase_      							=			torch.tensor([0.2_4_3_3, 0.1_6_3_2, -0.4_8_9_4]	)
	elif model_name == "videomae-base-short-finetuned-kinetics":
		lowerCAmelCase_      							=			torch.Size([1, 4_0_0]	)
		lowerCAmelCase_      							=			torch.tensor([0.6_5_8_8, 0.0_9_9_0, -0.2_4_9_3]	)
	elif model_name == "videomae-base-finetuned-kinetics":
		lowerCAmelCase_      							=			torch.Size([1, 4_0_0]	)
		lowerCAmelCase_      							=			torch.tensor([0.3_6_6_9, -0.0_6_8_8, -0.2_4_2_1]	)
	elif model_name == "videomae-base-short-ssv2":
		lowerCAmelCase_      							=			torch.Size([1, 1_4_0_8, 1_5_3_6]	)
		lowerCAmelCase_      							=			torch.tensor([[0.4_7_1_2, 0.5_2_9_6, 0.5_7_8_6], [0.2_2_7_8, 0.2_7_2_9, 0.4_0_2_6], [0.0_3_5_2, 0.0_7_3_0, 0.2_5_0_6]]	)
	elif model_name == "videomae-base-short-finetuned-ssv2":
		lowerCAmelCase_      							=			torch.Size([1, 1_7_4]	)
		lowerCAmelCase_      							=			torch.tensor([-0.0_5_3_7, -0.1_5_3_9, -0.3_2_6_6]	)
	elif model_name == "videomae-base-ssv2":
		lowerCAmelCase_      							=			torch.Size([1, 1_4_0_8, 1_5_3_6]	)
		lowerCAmelCase_      							=			torch.tensor([[0.8_1_3_1, 0.8_7_2_7, 0.8_5_4_6], [0.7_3_6_6, 0.9_3_7_7, 0.8_8_7_0], [0.5_9_3_5, 0.8_8_7_4, 0.8_5_6_4]]	)
	elif model_name == "videomae-base-finetuned-ssv2":
		lowerCAmelCase_      							=			torch.Size([1, 1_7_4]	)
		lowerCAmelCase_      							=			torch.tensor([0.1_9_6_1, -0.8_3_3_7, -0.6_3_8_9]	)
	else:
		raise ValueError(F"""Model name not supported. Should be one of {model_names}"""	)

	# verify logits
	assert logits.shape == expected_shape
	if "finetuned" in model_name:
		assert torch.allclose(logits[0, :3]			,   _lowercase			,   atol=1E-4	)
	else:
		print('''Logits:'''			,   logits[0, :3, :3]	)
		assert torch.allclose(logits[0, :3, :3]			,   _lowercase			,   atol=1E-4	)
	print('''Logits ok!'''	)

	# verify loss, if applicable
	if model_name == "videomae-base-short":
		lowerCAmelCase_      							=			outputs.loss
		assert torch.allclose(_lowercase			,   _lowercase			,   atol=1E-4	)
		print('''Loss ok!'''	)

	if pytorch_dump_folder_path is not None:
		print(F"""Saving model and image processor to {pytorch_dump_folder_path}"""	)
		image_processor.save_pretrained(_lowercase	)
		model.save_pretrained(_lowercase	)

	if push_to_hub:
		print('''Pushing to the hub...'''	)
		model.push_to_hub(_lowercase			,   organization='''nielsr'''	)


if __name__ == "__main__":
		lowercase_							=							argparse.ArgumentParser()
		# Required parameters
		parser.add_argument(
		    '--checkpoint_url',
		    default='https://drive.google.com/u/1/uc?id=1tEhLyskjb755TJ65ptsrafUG2llSwQE1&amp;export=download&amp;confirm=t&amp;uuid=aa3276eb-fb7e-482a-adec-dc7171df14c4',
		    type=str,
		    help=(
		        'URL of the original PyTorch checkpoint (on Google Drive) you\'d like to convert. Should be a direct'
		        ' download link.'
		    ),
		)
		parser.add_argument(
		    '--pytorch_dump_folder_path',
		    default='/Users/nielsrogge/Documents/VideoMAE/Test',
		    type=str,
		    help='Path to the output PyTorch model directory.',
		)
		parser.add_argument('--model_name', default='videomae-base', type=str, help='Name of the model.')
		parser.add_argument(
		    '--push_to_hub', action='store_true', help='Whether or not to push the converted model to the 🤗 hub.'
		)

		lowercase_							=							parser.parse_args()
		convert_videomae_checkpoint(args.checkpoint_url, args.pytorch_dump_folder_path, args.model_name, args.push_to_hub)



"""simple docstring"""



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

import pytest

from .sola import PokerHand

lowercase_							=							(
    '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)
)

lowercase_							=							(
    ('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'),
)

lowercase_							=							(
    ('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),
)

lowercase_							=							(
    ('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),
)

lowercase_							=							(
    ('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]),
)

lowercase_							=							(
    ('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),
)

lowercase_							=							(
    ('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      UpperCAmelCase     (       )						-> List[str]:


	"""simple docstring"""




	lowerCAmelCase_							,	lowerCAmelCase_      							=			randrange(len(_lowercase	)	), randrange(len(_lowercase	)	)
	lowerCAmelCase_      							=			['''Loss''', '''Tie''', '''Win'''][(play >= oppo) + (play > oppo)]
	lowerCAmelCase_							,	lowerCAmelCase_      							=			SORTED_HANDS[play], SORTED_HANDS[oppo]
	return hand, other, expected
def      UpperCAmelCase     (       _lowercase :   int = 1_0_0	)						-> int:


	"""simple docstring"""




	return (generate_random_hand() for _ in range(_lowercase	))
@pytest.mark.parametrize('''hand, expected'''			,   _lowercase	)
def      UpperCAmelCase     (       _lowercase :   Union[str, Any]			,   _lowercase :   Optional[int]	)						-> str:


	"""simple docstring"""




	assert PokerHand(_lowercase	)._is_flush() == expected
@pytest.mark.parametrize('''hand, expected'''			,   _lowercase	)
def      UpperCAmelCase     (       _lowercase :   List[Any]			,   _lowercase :   List[str]	)						-> Optional[Any]:


	"""simple docstring"""




	assert PokerHand(_lowercase	)._is_straight() == expected
@pytest.mark.parametrize('''hand, expected, card_values'''			,   _lowercase	)
def      UpperCAmelCase     (       _lowercase :   str			,   _lowercase :   Any			,   _lowercase :   Union[str, Any]	)						-> str:


	"""simple docstring"""




	lowerCAmelCase_      							=			PokerHand(_lowercase	)
	assert player._is_five_high_straight() == expected
	assert player._card_values == card_values
@pytest.mark.parametrize('''hand, expected'''			,   _lowercase	)
def      UpperCAmelCase     (       _lowercase :   Any			,   _lowercase :   Union[str, Any]	)						-> Optional[Any]:


	"""simple docstring"""




	assert PokerHand(_lowercase	)._is_same_kind() == expected
@pytest.mark.parametrize('''hand, expected'''			,   _lowercase	)
def      UpperCAmelCase     (       _lowercase :   Tuple			,   _lowercase :   int	)						-> str:


	"""simple docstring"""




	assert PokerHand(_lowercase	)._hand_type == expected
@pytest.mark.parametrize('''hand, other, expected'''			,   _lowercase	)
def      UpperCAmelCase     (       _lowercase :   int			,   _lowercase :   str			,   _lowercase :   Tuple	)						-> Union[str, Any]:


	"""simple docstring"""




	assert PokerHand(_lowercase	).compare_with(PokerHand(_lowercase	)	) == expected
@pytest.mark.parametrize('''hand, other, expected'''			,   generate_random_hands()	)
def      UpperCAmelCase     (       _lowercase :   Any			,   _lowercase :   Dict			,   _lowercase :   Dict	)						-> Union[str, Any]:


	"""simple docstring"""




	assert PokerHand(_lowercase	).compare_with(PokerHand(_lowercase	)	) == expected
def      UpperCAmelCase     (       )						-> List[str]:


	"""simple docstring"""




	lowerCAmelCase_      							=			[PokerHand(_lowercase	) for hand in SORTED_HANDS]
	lowerCAmelCase_      							=			poker_hands.copy()
	shuffle(_lowercase	)
	lowerCAmelCase_      							=			chain(sorted(_lowercase	)	)
	for index, hand in enumerate(_lowercase	):
		assert hand == poker_hands[index]
def      UpperCAmelCase     (       )						-> Any:


	"""simple docstring"""




	lowerCAmelCase_      							=			[PokerHand('''2D AC 3H 4H 5S'''	), PokerHand('''2S 3H 4H 5S 6C'''	)]
	pokerhands.sort(reverse=_lowercase	)
	assert pokerhands[0].__str__() == "2S 3H 4H 5S 6C"
def      UpperCAmelCase     (       )						-> List[str]:


	"""simple docstring"""




	lowerCAmelCase_      							=			PokerHand('''2C 4S AS 3D 5C'''	)
	lowerCAmelCase_      							=			True
	lowerCAmelCase_      							=			[5, 4, 3, 2, 1_4]
	for _ in range(1_0	):
		assert pokerhand._is_five_high_straight() == expected
		assert pokerhand._card_values == expected_card_values





def      UpperCAmelCase     (       )						-> Dict:


	"""simple docstring"""




	lowerCAmelCase_      							=			0
	lowerCAmelCase_      							=			os.path.abspath(os.path.dirname(_lowercase	)	)
	lowerCAmelCase_      							=			os.path.join(_lowercase			,   '''poker_hands.txt'''	)
	with open(_lowercase	) as file_hand:
		for line in file_hand:
			lowerCAmelCase_      							=			line[:1_4].strip()
			lowerCAmelCase_      							=			line[1_5:].strip()
			lowerCAmelCase_							,	lowerCAmelCase_      							=			PokerHand(_lowercase	), PokerHand(_lowercase	)
			lowerCAmelCase_      							=			player.compare_with(_lowercase	)
			if output == "Win":
				answer += 1
	assert answer == 3_7_6