<commit_before>import re

class MalformedTAF(Exception):
    def __init__(self, msg):
        self.strerror = msg

class TAF(object):
    """ TAF "envelope" parser """

    def __init__(self, string):
        """
        Initializes the object with TAF/METAR report text.

        Args:
            string: TAF/METAR report string

        Raises:
            MalformedTAF: An error parsing the TAF/METAR report
        """

        # Instance variables
        self._raw_taf = None
        self._taf_header = None
        self._raw_weather_groups = []
        self._weather_groups = []
        self._maintenance = None

        if isinstance(string, str) and string != "":
            self._raw_taf = string
        else:
            raise MalformedTAF("TAF/METAR string expected")

        # Patterns use ^ and $, so we don't want
        # leading/trailing spaces
        self._raw_taf = self._raw_taf.strip()

        # Initialize header part
        self._taf_header = self._init_header(self._raw_taf)

        if self._taf_header['form'] == 'metar':
            self._weather_groups.append(self._parse_group(self._raw_taf))
        else:
            # Get all TAF weather groups
            self._raw_weather_groups = self._init_groups(self._raw_taf)

            for group in self._raw_weather_groups:
                parsed_group = self._parse_group(group)
                self._weather_groups.append(parsed_group)

        self._maintenance = self._parse_maintenance(self._raw_taf)

    def _init_header(self, string):
        """ Extracts header part from TAF/METAR string and populates header dict

        Args:
            TAF/METAR report string

        Raises:
            MalformedTAF: An error parsing the report

        Returns:
            Header dictionary
        """

        taf_header_pattern = """
            ^
            (TAF)?    # TAF header (at times missing or duplicate)
            \s*
            (?P<type> (COR|AMD|RTD)){0,1} # Corrected/Amended/Delayed

            \s* # There may or may not be space as COR/AMD/RTD is optional
            (?P<icao_code> [A-Z]{4}) # Station ICAO code

            \s* # at some aerodromes does not appear
            (?P<origin_date> \d{0,2}) # at some aerodromes does not appear
            (?P<origin_hours> \d{0,2}) # at some aerodromes does not appear
            (?P<origin_minutes> \d{0,2}) # at some aerodromes does not appear
            Z? # Zulu time (UTC, that is) # at some aerodromes does not appear

            \s*
            (?P<valid_from_date> \d{0,2})
            (?P<valid_from_hours> \d{0,2})
            /
            (?P<valid_till_date> \d{0,2})
            (?P<valid_till_hours> \d{0,2})
        """

        metar_header_pattern = """
            ^
            (METAR)?    # METAR header (at times missing or duplicate)
            \s*
            (?P<icao_code> [A-Z]{4}) # Station ICAO code

            \s* # at some aerodromes does not appear
            (?P<origin_date> \d{0,2}) # at some aerodromes does not appear
            (?P<origin_hours> \d{0,2}) # at some aerodromes does not appear
            (?P<origin_minutes> \d{0,2}) # at some aerodromes does not appear
            Z? # Zulu time (UTC, that is) # at some aerodromes does not appear
            \s+<commit_msg>Allow for COR + AMD type<commit_after>import re

class MalformedTAF(Exception):
    def __init__(self, msg):
        self.strerror = msg

class TAF(object):
    """ TAF "envelope" parser """

    def __init__(self, string):
        """
        Initializes the object with TAF/METAR report text.

        Args:
            string: TAF/METAR report string

        Raises:
            MalformedTAF: An error parsing the TAF/METAR report
        """

        # Instance variables
        self._raw_taf = None
        self._taf_header = None
        self._raw_weather_groups = []
        self._weather_groups = []
        self._maintenance = None

        if isinstance(string, str) and string != "":
            self._raw_taf = string
        else:
            raise MalformedTAF("TAF/METAR string expected")

        # Patterns use ^ and $, so we don't want
        # leading/trailing spaces
        self._raw_taf = self._raw_taf.strip()

        # Initialize header part
        self._taf_header = self._init_header(self._raw_taf)

        if self._taf_header['form'] == 'metar':
            self._weather_groups.append(self._parse_group(self._raw_taf))
        else:
            # Get all TAF weather groups
            self._raw_weather_groups = self._init_groups(self._raw_taf)

            for group in self._raw_weather_groups:
                parsed_group = self._parse_group(group)
                self._weather_groups.append(parsed_group)

        self._maintenance = self._parse_maintenance(self._raw_taf)

    def _init_header(self, string):
        """ Extracts header part from TAF/METAR string and populates header dict

        Args:
            TAF/METAR report string

        Raises:
            MalformedTAF: An error parsing the report

        Returns:
            Header dictionary
        """

        taf_header_pattern = """
            ^
            (TAF)?    # TAF header (at times missing or duplicate)
            \s*
            (?P<type> (COR|AMD|AMD\sCOR|COR\sAMD|RTD)){0,1} # Corrected/Amended/Amended and Corrected|Corrected and Amended|Delayed

            \s* # There may or may not be space as COR/AMD/RTD is optional
            (?P<icao_code> [A-Z]{4}) # Station ICAO code

            \s* # at some aerodromes does not appear
            (?P<origin_date> \d{0,2}) # at some aerodromes does not appear
            (?P<origin_hours> \d{0,2}) # at some aerodromes does not appear
            (?P<origin_minutes> \d{0,2}) # at some aerodromes does not appear
            Z? # Zulu time (UTC, that is) # at some aerodromes does not appear

            \s*
            (?P<valid_from_date> \d{0,2})
            (?P<valid_from_hours> \d{0,2})
            /
            (?P<valid_till_date> \d{0,2})
            (?P<valid_till_hours> \d{0,2})
        """

        metar_header_pattern = """
            ^
            (METAR)?    # METAR header (at times missing or duplicate)
            \s*
            (?P<icao_code> [A-Z]{4}) # Station ICAO code

            \s* # at some aerodromes does not appear
            (?P<origin_date> \d{0,2}) # at some aerodromes does not appear
            (?P<origin_hours> \d{0,2}) # at some aerodromes does not appear
            (?P<origin_minutes> \d{0,2}) # at some aerodromes does not appear
            Z? # Zulu time (UTC, that is) # at some aerodromes does not appear
            \s+
{'fraction_non_alphanumeric': 0.1034794396746498, 'fraction_numerical': 0.0072300045187528245, 'mean_word_length': 1.8694900605012965, 'pattern_counts': {'":': 2, '<': 29, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6369486', 'n_tokens_mistral': 2147, 'n_tokens_neox': 1996, 'n_words': 535}