



"""simple docstring"""






import collections
import json
import math
import os
import re
import time
from fnmatch import fnmatch
from typing import Dict

import requests
from slack_sdk import WebClient


_lowercase			:			int										=      WebClient(token=os.environ["CI_SLACK_BOT_TOKEN"])






def 					snake_case__       (		__lowerCamelCase    :   int     ):
			"""simple docstring"""
			lowerCamelCase__		:		Tuple		     =test_results.split(''' '''     )

			lowerCamelCase__		:		Dict		     =0
			lowerCamelCase__		:		Dict		     =0

			# When the output is short enough, the output is surrounded by = signs: "== OUTPUT =="
			# When it is too long, those signs are not present.
			lowerCamelCase__		:		List[str]		     =expressions[-2] if '''=''' in expressions[-1] else expressions[-1]

			for i, expression in enumerate(snake_case_     ):
						if "failed" in expression:
									failed += int(expressions[i - 1]     )
						if "passed" in expression:
									success += int(expressions[i - 1]     )

			return failed, success, time_spent






def 					snake_case__       (		__lowerCamelCase    :   str     ):
			"""simple docstring"""
			lowerCamelCase__		:		Optional[int]		     ={}
			lowerCamelCase__		:		int		     =None
			lowerCamelCase__		:		Dict		     =False
			for line in failures_short_lines.split('''\n'''     ):
						if re.search(R'''_ \[doctest\]'''							,		snake_case_     ):
									lowerCamelCase__		:		Optional[Any]		     =True
									lowerCamelCase__		:		List[str]		     =line.split(''' '''     )[2]
						elif in_error and not line.split(''' '''     )[0].isdigit():
									lowerCamelCase__		:		Optional[Any]		     =line
									lowerCamelCase__		:		int		     =False

			return failures

class 	__SCREAMING_SNAKE_CASE     :


					'''simple docstring'''





					def __init__(	self							:  Optional[Any],  lowerCamelCase							:  str,  lowerCamelCase							:  Dict					)-> Optional[Any]:
								lowerCamelCase__		:		Tuple		     =title

								lowerCamelCase__		:		Optional[Any]		     =doc_test_results['''time_spent'''].split(''','''					)[0]
								lowerCamelCase__		:		str		     =doc_test_results['''success''']
								lowerCamelCase__		:		Optional[Any]		     =doc_test_results['''failures''']
								lowerCamelCase__		:		List[str]		     =self.n_success + self.n_failures

								# Failures and success of the modeling tests
								lowerCamelCase__		:		Optional[Any]		     =doc_test_results



					@property
					def 		snake_case	(	self							:  Optional[Any]					)-> Union[str, Any]:
								lowerCamelCase__		:		Union[str, Any]		     =[self._time_spent]
								lowerCamelCase__		:		Any		     =0

								for time in time_spent:
											lowerCamelCase__		:		int		     =time.split(''':'''					)

											# Time can be formatted as xx:xx:xx, as .xx, or as x.xx if the time spent was less than a minute.
											if len(_lowercase					) == 1:
														lowerCamelCase__		:		Union[str, Any]		     =[0, 0, time_parts[0]]

											lowerCamelCase__     ,       lowerCamelCase__     ,       lowerCamelCase__		:		Dict		     =int(time_parts[0]					), int(time_parts[1]					), float(time_parts[2]					)
											total_secs += hours * 3600 + minutes * 60 + seconds

								lowerCamelCase__     ,       lowerCamelCase__     ,       lowerCamelCase__		:		Union[str, Any]		     =total_secs // 3600, (total_secs % 3600) // 60, total_secs % 60
								return F'''{int(_lowercase					)}h{int(_lowercase					)}m{int(_lowercase					)}s'''



					@property
					def 		snake_case	(	self							:  List[str]					)-> List[Any]:
								return {"type": "header", "text": {"type": "plain_text", "text": self.title}}



					@property
					def 		snake_case	(	self							:  Any					)-> Dict:
								return {
								    "type": "section",
								    "text": {
								        "type": "plain_text",
								        "text": F'''🌞 There were no failures: all {self.n_tests} tests passed. The suite ran in {self.time}.''',
								        "emoji": True,
								    },
								    "accessory": {
								        "type": "button",
								        "text": {"type": "plain_text", "text": "Check Action results", "emoji": True},
								        "url": F'''https://github.com/huggingface/transformers/actions/runs/{os.environ["GITHUB_RUN_ID"]}''',
								    },
								}



					@property
					def 		snake_case	(	self							:  Any					)-> Union[str, Any]:
								return {
								    "type": "section",
								    "text": {
								        "type": "plain_text",
								        "text": (
								            F'''There were {self.n_failures} failures, out of {self.n_tests} tests.\nThe suite ran in'''
								            F''' {self.time}.'''
								        ),
								        "emoji": True,
								    },
								    "accessory": {
								        "type": "button",
								        "text": {"type": "plain_text", "text": "Check Action results", "emoji": True},
								        "url": F'''https://github.com/huggingface/transformers/actions/runs/{os.environ["GITHUB_RUN_ID"]}''',
								    },
								}



					@property
					def 		snake_case	(	self							:  List[Any]					)-> Any:
								lowerCamelCase__		:		Optional[Any]		     =40
								lowerCamelCase__		:		str		     ={k: v['''failed'''] for k, v in doc_test_results.items() if isinstance(_lowercase,  _lowercase					)}

								lowerCamelCase__		:		Union[str, Any]		     =''''''
								for category, failures in category_failures.items():
											if len(_lowercase					) == 0:
														continue

											if report != "":
														report += "\n\n"

											report += F'''*{category} failures*:'''.ljust(line_length // 2					).rjust(line_length // 2					) + "\n"
											report += "`"
											report += "`\n`".join(_lowercase					)
											report += "`"

								return {
								    "type": "section",
								    "text": {
								        "type": "mrkdwn",
								        "text": F'''The following examples had failures:\n\n\n{report}\n''',
								    },
								}



					@property
					def 		snake_case	(	self							:  Union[str, Any]					)-> Optional[int]:
								lowerCamelCase__		:		Any		     =[self.header]

								if self.n_failures > 0:
											blocks.append(self.failures					)

								if self.n_failures > 0:
											blocks.extend([self.category_failures]					)

								if self.n_failures == 0:
											blocks.append(self.no_failures					)

								return json.dumps(_lowercase					)



					@staticmethod
					def 		snake_case	(	)-> Optional[Any]:
								lowerCamelCase__		:		Any		     =[
								    {
								        '''type''': '''section''',
								        '''text''': {
								            '''type''': '''plain_text''',
								            '''text''': '''There was an issue running the tests.''',
								        },
								        '''accessory''': {
								            '''type''': '''button''',
								            '''text''': {'''type''': '''plain_text''', '''text''': '''Check Action results''', '''emoji''': True},
								            '''url''': F'''https://github.com/huggingface/transformers/actions/runs/{os.environ["GITHUB_RUN_ID"]}''',
								        },
								    }
								]

								print('''Sending the following payload'''					)
								print(json.dumps({'''blocks''': json.loads(_lowercase					)}					)					)

								client.chat_postMessage(
								    channel=os.environ['''CI_SLACK_CHANNEL_ID_DAILY'''],  text='''There was an issue running the tests.''',  blocks=_lowercase,  )



					def 		snake_case	(	self							:  int					)-> Union[str, Any]:
								print('''Sending the following payload'''					)
								print(json.dumps({'''blocks''': json.loads(self.payload					)}					)					)

								lowerCamelCase__		:		Optional[Any]		     =F'''{self.n_failures} failures out of {self.n_tests} tests,''' if self.n_failures else '''All tests passed.'''

								lowerCamelCase__		:		List[Any]		     =client.chat_postMessage(
								    channel=os.environ['''CI_SLACK_CHANNEL_ID_DAILY'''],  blocks=self.payload,  text=_lowercase,  )



					def 		snake_case	(	self							:  Tuple,  lowerCamelCase							:  List[str],  lowerCamelCase							:  Optional[Any],  lowerCamelCase							:  Optional[Any],  lowerCamelCase							:  Dict					)-> int:
								lowerCamelCase__		:		Dict		     =''''''
								for key, value in failures.items():
											lowerCamelCase__		:		Union[str, Any]		     =value[:200] + ''' [Truncated]''' if len(_lowercase					) > 250 else value
											failures_text += F'''*{key}*\n_{value}_\n\n'''

								lowerCamelCase__		:		List[Any]		     =job_name
								lowerCamelCase__		:		Optional[int]		     ={'''type''': '''section''', '''text''': {'''type''': '''mrkdwn''', '''text''': text}}

								if job_link is not None:
											lowerCamelCase__		:		List[Any]		     ={
											    '''type''': '''button''',
											    '''text''': {'''type''': '''plain_text''', '''text''': '''GitHub Action job''', '''emoji''': True},
											    '''url''': job_link,
											}

								return [
								    {"type": "header", "text": {"type": "plain_text", "text": title.upper(), "emoji": True}},
								    content,
								    {"type": "section", "text": {"type": "mrkdwn", "text": failures_text}},
								]




					def 		snake_case	(	self							:  Union[str, Any]					)-> Optional[int]:
								if self.thread_ts is None:
											raise ValueError('''Can only post reply if a post has been made.'''					)

								lowerCamelCase__		:		Optional[int]		     =self.doc_test_results.pop('''job_link'''					)
								self.doc_test_results.pop('''failures'''					)
								self.doc_test_results.pop('''success'''					)
								self.doc_test_results.pop('''time_spent'''					)

								lowerCamelCase__		:		List[str]		     =sorted(self.doc_test_results.items(),  key=lambda lowerCamelCase					: t[0]					)
								for job, job_result in sorted_dict:
											if len(job_result['''failures''']					):
														lowerCamelCase__		:		List[str]		     =F'''*Num failures* :{len(job_result["failed"]					)} \n'''
														lowerCamelCase__		:		Optional[Any]		     =job_result['''failures''']
														lowerCamelCase__		:		Tuple		     =self.get_reply_blocks(_lowercase,  _lowercase,  _lowercase,  text=_lowercase					)

														print('''Sending the following reply'''					)
														print(json.dumps({'''blocks''': blocks}					)					)

														client.chat_postMessage(
														    channel=os.environ['''CI_SLACK_CHANNEL_ID_DAILY'''],  text=F'''Results for {job}''',  blocks=_lowercase,  thread_ts=self.thread_ts['''ts'''],  )

														time.sleep(1					)






def 					snake_case__       (		):
			"""simple docstring"""
			lowerCamelCase__		:		Dict		     =os.environ['''GITHUB_RUN_ID''']
			lowerCamelCase__		:		Dict		     =f'''https://api.github.com/repos/huggingface/transformers/actions/runs/{run_id}/jobs?per_page=100'''
			lowerCamelCase__		:		Any		     =requests.get(snake_case_     ).json()
			lowerCamelCase__		:		Tuple		     ={}

			try:
						jobs.update({job['''name''']: job['''html_url'''] for job in result['''jobs''']}     )
						lowerCamelCase__		:		Tuple		     =math.ceil((result['''total_count'''] - 100) / 100     )

						for i in range(snake_case_     ):
									lowerCamelCase__		:		List[Any]		     =requests.get(url + f'''&page={i + 2}'''     ).json()
									jobs.update({job['''name''']: job['''html_url'''] for job in result['''jobs''']}     )

						return jobs
			except Exception as e:
						print('''Unknown error, could not fetch links.'''							,		snake_case_     )

			return {}






def 					snake_case__       (		__lowerCamelCase    :   str     ):
			"""simple docstring"""
			lowerCamelCase__		:		Tuple		     ={}

			if os.path.exists(snake_case_     ):
						lowerCamelCase__		:		Optional[Any]		     =os.listdir(snake_case_     )
						for file in files:
									try:
												with open(os.path.join(snake_case_							,		snake_case_     )							,		encoding='''utf-8'''     ) as f:
															lowerCamelCase__		:		int		     =f.read()
									except UnicodeDecodeError as e:
												raise ValueError(f'''Could not open {os.path.join(snake_case_							,		snake_case_     )}.'''     ) from e

			return _artifact






def 					snake_case__       (		):
			"""simple docstring"""

			class 	__SCREAMING_SNAKE_CASE     :


								'''simple docstring'''





								def __init__(	self							:  Optional[Any],  lowerCamelCase							:  str					)-> str:
											lowerCamelCase__		:		int		     =name
											lowerCamelCase__		:		Optional[int]		     =[]



								def __str__(	self							:  int					)-> List[Any]:
											return self.name




								def 		snake_case	(	self							:  Any,  lowerCamelCase							:  str					)-> int:
											self.paths.append({'''name''': self.name, '''path''': path}					)





			lowerCamelCase__		:		int		     ={}

			lowerCamelCase__		:		Tuple		     =filter(os.path.isdir							,		os.listdir()     )
			for directory in directories:
						lowerCamelCase__		:		str		     =directory
						if artifact_name not in _available_artifacts:
									lowerCamelCase__		:		str		     =Artifact(snake_case_     )

									_available_artifacts[artifact_name].add_path(snake_case_     )

			return _available_artifacts


if __name__ == "__main__":
		_lowercase			:			str										=      get_job_links()
		_lowercase			:			Optional[int]										=      retrieve_available_artifacts()

		_lowercase			:			List[str]										=      collections.OrderedDict(
		    [
		        ("*.py", "API Examples"),
		        ("*.md", "MD Examples"),
		    ]
		)

		# This dict will contain all the information relative to each doc test category:
		# - failed: list of failed tests
		# - failures: dict in the format 'test': 'error_message'
		_lowercase			:			List[str]										=      {
		    v: {
		        'failed': [],
		        'failures': {},
		    }
		    for v in docs.values()
		}

		# Link to the GitHub Action job
		_lowercase			:			Optional[int]										=      github_actions_job_links.get("run_doctests")

		_lowercase			:			Optional[int]										=      available_artifacts['doc_tests_gpu_test_reports'].paths[0]
		_lowercase			:			Any										=      retrieve_artifact(artifact_path["name"])
		if "stats" in artifact:
				_lowercase			:			Dict										=      handle_test_results(artifact["stats"])
				_lowercase			:			int										=      failed
				_lowercase			:			Union[str, Any]										=      success
				_lowercase			:			List[Any]										=      time_spent[1:-1] + ', '

				_lowercase			:			List[str]										=      extract_first_line_failure(artifact["failures_short"])
				for line in artifact["summary_short"].split("\n"):
						if re.search("FAILED", line):
								_lowercase			:			Optional[int]										=      line.replace("FAILED ", "")
								_lowercase			:			Optional[int]										=      line.split()[0].replace("\n", "")

								if "::" in line:
										_lowercase			:			Any										=      line.split("::")
								else:
										_lowercase			:			List[Any]										=      line, line

								for file_regex in docs.keys():
										if fnmatch(file_path, file_regex):
												_lowercase			:			List[str]										=      docs[file_regex]
												doc_test_results[category]["failed"].append(test)

												_lowercase			:			Union[str, Any]										=      all_failures[test] if test in all_failures else 'N/A'
												_lowercase			:			List[Any]										=      failure
												break

		_lowercase			:			Union[str, Any]										=      Message("🤗 Results of the doc tests.", doc_test_results)
		message.post()
		message.post_reply()









"""simple docstring"""






from collections import defaultdict

class 	__SCREAMING_SNAKE_CASE     :


					'''simple docstring'''





					def __init__(	self							:  Union[str, Any],  lowerCamelCase							:  List[Any],  lowerCamelCase							:  List[str]					)-> Optional[int]:
								lowerCamelCase__		:		List[Any]		     =total  # total no of tasks (N)

								# DP table will have a dimension of (2^M)*N
								# initially all values are set to -1
								lowerCamelCase__		:		Optional[Any]		     =[
								    [-1 for i in range(total + 1					)] for j in range(2 ** len(lowerCamelCase					)					)
								]

								lowerCamelCase__		:		Any		     =defaultdict(lowerCamelCase					)  # stores the list of persons for each task

								# final_mask is used to check if all persons are included by setting all bits
								# to 1
								lowerCamelCase__		:		List[Any]		     =(1 << len(lowerCamelCase					)) - 1



					def 		snake_case	(	self							:  int,  lowerCamelCase							:  str,  lowerCamelCase							:  Any					)-> Any:
								# if mask == self.finalmask all persons are distributed tasks, return 1
								if mask == self.final_mask:
											return 1

								# if not everyone gets the task and no more tasks are available, return 0
								if task_no > self.total_tasks:
											return 0

								# if case already considered
								if self.dp[mask][task_no] != -1:
											return self.dp[mask][task_no]

								# Number of ways when we don't this task in the arrangement
								lowerCamelCase__		:		Optional[int]		     =self.count_ways_until(lowerCamelCase,  task_no + 1					)

								# now assign the tasks one by one to all possible persons and recursively
								# assign for the remaining tasks.
								if task_no in self.task:
											for p in self.task[task_no]:
														# if p is already given a task
														if mask & (1 << p):
																	continue

														# assign this task to p and change the mask value. And recursively
														# assign tasks with the new mask value.
														total_ways_util += self.count_ways_until(mask | (1 << p),  task_no + 1					)

        # save the value.
								lowerCamelCase__		:		int		     =total_ways_util

								return self.dp[mask][task_no]




					def 		snake_case	(	self							:  Dict,  lowerCamelCase							:  Dict					)-> int:
								# Store the list of persons for each task
								for i in range(len(lowerCamelCase					)					):
											for j in task_performed[i]:
														self.task[j].append(lowerCamelCase					)

        # call the function to fill the DP table, final answer is stored in dp[0][1]
								return self.count_ways_until(0,  1					)


if __name__ == "__main__":
		_lowercase			:			Tuple										=						5  # total no of tasks (the value of N)

		# the list of tasks that can be done by M persons.
		_lowercase			:			Dict										=						[[1, 3, 4], [1, 2, 5], [3, 4]]
		print(
		    AssignmentUsingBitmask(task_performed, total_tasks).count_no_of_ways(
		        task_performed
		    )
		)




