




'''simple docstring'''






import logging
from pathlib import Path
from typing import Any, List, Tuple

import yaml


# loading package files: https://stackoverflow.com/a/20885799
try:
      import importlib.resources as pkg_resources
except ImportError:
      # Try backported to PY<37 `importlib_resources`.
      import importlib_resources as pkg_resources

from . import resources


A_ 			=		"https://github.com/huggingface/datasets/tree/main/src/datasets/utils"
A_ 			=		F'{BASE_REF_URL}/{__file__}'
A_ 			=		logging.getLogger(__name__)






def 		UpperCamelCase__			(		__SCREAMING_SNAKE_CASE		)						->      Tuple[Any, str]:
      snake_case__					:      List[str]  			=						pkg_resources.read_text(__SCREAMING_SNAKE_CASE							,			__SCREAMING_SNAKE_CASE		)
      return yaml.safe_load(__SCREAMING_SNAKE_CASE		), f"{BASE_REF_URL}/resources/{resource}"


A_			,						A_ 			=		load_yaml_resource("readme_structure.yaml")

A_ 			=		[
    "[Needs More Information]",
    "[More Information Needed]",
    "(https://github.com/huggingface/datasets/blob/main/CONTRIBUTING.md#how-to-contribute-to-the-dataset-cards)",
]

# Dictionary representation of section/readme, error_list, warning_list
A_ 			=		Tuple[dict, List[str], List[str]]






class 					lowercase_			:





     def __init__(    self    :				Any    ,       __lowerCamelCase    :				str    ,       __lowerCamelCase    :				str    ,       __lowerCamelCase    :				List[str] = None    ,       __lowerCamelCase    :				bool = False ):
           snake_case__					:      Optional[Any]  			=						name
           snake_case__					:      Union[str, Any]  			=						level
           snake_case__					:      Any  			=						lines
           snake_case__					:      List[Any]  			=						''
           snake_case__					:      Dict  			=						True
           snake_case__					:      Dict  			=						{}
           snake_case__					:      List[str]  			=						[]
           snake_case__					:      int  			=						[]
           if self.lines is not None:
                 self.parse(suppress_parsing_errors=__lowerCamelCase )





     def  _lowerCAmelCase			(    self    :				Tuple    ,       __lowerCamelCase    :				bool = False ):
           snake_case__					:      int  			=						''
           snake_case__					:      List[str]  			=						[]
           snake_case__					:      Union[str, Any]  			=						False
           for line in self.lines:
                 if line.strip(' \n' ) == "":
                       continue
                 elif line.strip(' \n' )[:3] == "```":
                       snake_case__					:      Dict  			=						not code_start
                 elif line.split()[0] == self.level + "#" and not code_start:
                       if current_sub_level != "":
                             snake_case__					:      Dict  			=						Section(__lowerCamelCase    ,       self.level + '#'    ,       __lowerCamelCase )
                             snake_case__					:      List[Any]  			=						[]
                       else:
                             if current_lines != []:
                                   self.text += "".join(__lowerCamelCase ).strip()
                                   if self.text != "" and self.text not in FILLER_TEXT:
                                         snake_case__					:      List[str]  			=						False
                                   snake_case__					:      Any  			=						[]

                       snake_case__					:      Optional[int]  			=						' '.join(line.split()[1:] ).strip(' \n' )
                 else:
                       current_lines.append(__lowerCamelCase )
           else:
                 if current_sub_level != "":
                       if current_sub_level in self.content:
                             self.parsing_error_list.append(
                                 F"Multiple sections with the same heading `{current_sub_level}` have been found. Please keep only one of these sections." )
                       snake_case__					:      int  			=						Section(__lowerCamelCase    ,       self.level + '#'    ,       __lowerCamelCase )
                 else:
                       if current_lines != []:
                             self.text += "".join(__lowerCamelCase ).strip()
                             if self.text != "" and self.text not in FILLER_TEXT:
                                   snake_case__					:      List[Any]  			=						False

           if self.level == "" and not suppress_parsing_errors:
                 if self.parsing_error_list != [] or self.parsing_warning_list != []:
                       snake_case__					:      Tuple  			=						'\n'.join('-\t' + x for x in self.parsing_error_list + self.parsing_warning_list )
                       snake_case__					:      Tuple  			=						F"The following issues were found while parsing the README at `{self.name}`:\n" + errors
                       raise ValueError(__lowerCamelCase )





     def  _lowerCAmelCase			(    self    :				Any    ,       __lowerCamelCase    :				dict ):
           snake_case__					:      Optional[Any]  			=						[]
           snake_case__					:      Optional[Any]  			=						[]
           if structure["allow_empty"] is False:
                 # If content is expected
                 if self.is_empty_text and self.content == {}:
                       # If no content is found, mention it in the error_list
                       error_list.append(F"Expected some content in section `{self.name}` but it is empty." )

           if structure["allow_empty_text"] is False:
                 # If some text is expected
                 if self.is_empty_text:
                       # If no text is found, mention it in the error_list
                       error_list.append(
                           F"Expected some text in section `{self.name}` but it is empty (text in subsections are ignored)." )
        # Subsections Validation
           if structure["subsections"] is not None:
                 # If subsections are expected
                 if self.content == {}:
                       # If no subsections are present
                       snake_case__					:      Optional[Any]  			=						[subsection['name'] for subsection in structure['subsections']]
                       # Mention the expected values in the error_list
                       error_list.append(
                           F"Section `{self.name}` expected the following subsections: {', '.join(['`'+x+'`' for x in values] )}. Found 'None'." )
                 else:
                       # If some subsections are present
                       snake_case__					:      Optional[int]  			=						[subsection['name'] for subsection in structure['subsections']]
                       snake_case__					:      Dict  			=						False
                       for idx, name in enumerate(__lowerCamelCase ):
                             if name not in self.content:
                                   # If the expected subsection is not present
                                   error_list.append(F"Section `{self.name}` is missing subsection: `{name}`." )
                                   snake_case__					:      Optional[Any]  			=						True
                             else:
                                   # If the subsection is present, validate subsection, return the result
                                   # and concat the errors from subsection to section error_list

                                   # Skip sublevel validation if current level is `###`
                                   if self.level == "###":
                                         continue
                                   else:
                                         snake_case__					:      Tuple  			=						self.content[name].validate(
                                             structure['subsections'][idx] )
                                   error_list += subsec_error_list
                                   warning_list += subsec_warning_list

                       if has_missing_subsections:  # we only allow to have extra subsections if all the other ones are here
                             for name in self.content:
                                   if name not in structure_names:
                                         # If an extra subsection is present
                                         warning_list.append(
                                             F"`{self.name}` has an extra subsection: `{name}`. Skipping further validation checks for this subsection as expected structure is unknown." )
           if error_list:
                 # If there are errors, do not return the dictionary as it is invalid
                 return {}, error_list, warning_list
           else:
                 return self.to_dict(), error_list, warning_list





     def  _lowerCAmelCase			(    self    :				List[Any] ):
           return {
               "name": self.name,
               "text": self.text,
               "is_empty_text": self.is_empty_text,
               "subsections": [value.to_dict() for value in self.content.values()],
           }






class 					lowercase_			(	lowerCAmelCase_       ):  # Level 0





     def __init__(    self    :				Dict    ,       __lowerCamelCase    :				str    ,       __lowerCamelCase    :				List[str]    ,       __lowerCamelCase    :				dict = None    ,       __lowerCamelCase    :				bool = False ):
           super().__init__(name=__lowerCamelCase    ,       level='' )  # Not using lines here as we need to use a child class parse
           snake_case__					:      Union[str, Any]  			=						structure
           snake_case__					:      int  			=						-2
           snake_case__					:      int  			=						0
           snake_case__					:      str  			=						lines
           if self.lines is not None:
                 self.parse(suppress_parsing_errors=__lowerCamelCase )





     def  _lowerCAmelCase			(    self    :				List[Any] ):
           if self.structure is None:
                 snake_case__					:      int  			=						self._validate(__lowerCamelCase )
           else:
                 snake_case__					:      str  			=						self._validate(self.structure )
           if error_list != [] or warning_list != []:
                 snake_case__					:      Optional[int]  			=						'\n'.join(['-\t' + x for x in error_list + warning_list] )
                 snake_case__					:      Optional[Any]  			=						F"The following issues were found for the README at `{self.name}`:\n" + errors
                 raise ValueError(__lowerCamelCase )





     @classmethod
     def  _lowerCAmelCase			(    cls    :				int    ,       __lowerCamelCase    :				Path    ,       __lowerCamelCase    :				dict = None    ,       __lowerCamelCase    :				bool = False ):
           with open(__lowerCamelCase    ,       encoding='utf-8' ) as f:
                 snake_case__					:      Dict  			=						f.readlines()
           return cls(__lowerCamelCase    ,       __lowerCamelCase    ,       __lowerCamelCase    ,       suppress_parsing_errors=__lowerCamelCase )





     @classmethod
     def  _lowerCAmelCase			(    cls    :				Dict    ,       __lowerCamelCase    :				str    ,       __lowerCamelCase    :				dict = None    ,       __lowerCamelCase    :				str = "root"    ,       __lowerCamelCase    :				bool = False ):
           snake_case__					:      int  			=						string.split('\n' )
           return cls(__lowerCamelCase    ,       __lowerCamelCase    ,       __lowerCamelCase    ,       suppress_parsing_errors=__lowerCamelCase )





     def  _lowerCAmelCase			(    self    :				Dict    ,       __lowerCamelCase    :				bool = False ):
           # Skip Tags
           snake_case__					:      Optional[Any]  			=						0

           for line in self.lines:
                 self.yaml_tags_line_count += 1
                 if line.strip(' \n' ) == "---":
                       self.tag_count += 1
                       if self.tag_count == 2:
                             break
                 line_count += 1
           if self.tag_count == 2:
                 snake_case__					:      Optional[int]  			=						self.lines[line_count + 1 :]  # Get the last + 1 th item.
           else:
                 snake_case__					:      Optional[int]  			=						self.lines[self.tag_count :]
           super().parse(suppress_parsing_errors=__lowerCamelCase )





     def __str__(    self    :				int ):
           return str(self.to_dict() )





     def  _lowerCAmelCase			(    self    :				List[str]    ,       __lowerCamelCase    :				Optional[int] ):
           snake_case__					:      Optional[Any]  			=						[]
           snake_case__					:      List[str]  			=						[]
           if self.yaml_tags_line_count == 0:
                 warning_list.append('Empty YAML markers are present in the README.' )
           elif self.tag_count == 0:
                 warning_list.append('No YAML markers are present in the README.' )
           elif self.tag_count == 1:
                 warning_list.append('Only the start of YAML tags present in the README.' )
           # Check how many first level sections are present.
           snake_case__					:      List[Any]  			=						len(self.content.keys() )
           if num_first_level_keys > 1:
                 # If more than one, add to the error list, continue
                 error_list.append(
                     F"The README has several first-level headings: {', '.join(['`'+x+'`' for x in list(self.content.keys() )] )}. Only one heading is expected. Skipping further validation for this README." )
           elif num_first_level_keys < 1:
                 # If less than one, append error.
                 error_list.append(
                     'The README has no first-level headings. One heading is expected. Skipping further validation for this README.' )

           else:
                 # If one exactly
                 snake_case__					:      int  			=						list(self.content.keys() )[0]  # Get the key
                 if start_key.startswith('Dataset Card for' ):  # Check correct start
                       # If the starting is correct, validate all the sections
                       snake_case__					:      Optional[int]  			=						self.content[start_key].validate(
                           readme_structure['subsections'][0] )
                       error_list += sec_error_list
                       warning_list += sec_warning_list
                 else:
                       # If not found, append error
                       error_list.append(
                           'No first-level heading starting with `Dataset Card for` found in README. Skipping further validation for this README.' )
           if error_list:
                 # If there are errors, do not return the dictionary as it is invalid
                 return {}, error_list, warning_list
           else:
                 return self.to_dict(), error_list, warning_list


if __name__ == "__main__":
      from argparse import ArgumentParser

      A_ 			=		ArgumentParser(usage="Validate the content (excluding YAML tags) of a README.md file.")
      ap.add_argument("readme_filepath")
      A_ 			=		ap.parse_args()
      A_ 			=		Path(args.readme_filepath)
      A_ 			=		ReadMe.from_readme(readme_filepath)







'''simple docstring'''






def 		UpperCamelCase__			(		__SCREAMING_SNAKE_CASE = 1000		)						->      int:
      snake_case__					:      List[str]  			=						0
      snake_case__					:      int  			=						(n - 1) // 3
      total += ((terms) * (6 + (terms - 1) * 3)) // 2  # total of an A.P.
      snake_case__					:      Optional[Any]  			=						(n - 1) // 5
      total += ((terms) * (10 + (terms - 1) * 5)) // 2
      snake_case__					:      Tuple  			=						(n - 1) // 15
      total -= ((terms) * (30 + (terms - 1) * 15)) // 2
      return total


if __name__ == "__main__":
      print(F'{solution() = }')
