import re


def normalize_dates(list_dates):
    """
    Converts a list of timeframes (type: string) into a normalized list of timeframes (type: string, all in the format YYYY only).
        Does not affect YYYYQ1-3 or YYYYM01-M11 since these will be filtered out

    Parameters
    ----------
    list_dates: list of strings (each string is a timeframe which can be in the format YYYYQ#, YYYYM##, YYYY-YYYY, or YYYY-YY)

    Returns
    -------
    normed_dates: list of normalized timeframes (type: string, all in the format YYYY only) based on the input list

    Examples
    --------
    >>> normalize_dates(['2011', '2011Q4','2011Q1', '2013M12','2013M09','2011-2012', '2013-14'])
    ['2011', '2011', '2011Q1', '2013', '2013M09', '2011', '2013']

    """

    normed_dates = []  # initialize blank list for collecting normalized timeframes
    not_normed_list = []  # initialize blank list for collection boolean values (from the not_normed variable)
    not_normed = True  # initially set the not_normed variable to False

    # iterate through each timeframe x in the input list_dates
    for x in list_dates:
        not_normed = True
        # initialize the cleaned_date variable as being the same value as the input timeframe x
        cleaned_date = x

        # for ranged timeframes (e.g., YYYY-YYYY or YYYY-YY), we get the earlier timeframe (e.g., for 2008-2009 -- we use 2008)
        m = re.match('(\d{4})-(\d{4})', str(x))  # search the string if it matches the format YYYY-YYYY
        m2 = re.match('(\d{4})-(\d{2})', str(x))  # search the string if it matches the format YYYY-YY
        n = re.match('(\d{4})Q4', str(x))
        o = re.match('(\d{4})M12', str(x))

        if m:
            cleaned_date = m.groups()[0]  # get the earlier timeframe

        elif m2:
            cleaned_date = m2.groups()[0]  # get the earlier timeframe
        elif n:
            cleaned_date = n.groups()[-1]
        elif o:
            cleaned_date = o.groups()[-1]

        # for monthly/quarterly dates (e.g., YYYYQ# or YYYYM##), we just map these to YYYY
        else:
            n = re.match('(\d{4})Q\d{1}', str(x))  # search the string if it matches the format YYYYQ#
            o = re.match('(\d{4})M\d{2}', str(x))  # search the string if it matches the format YYYYM##

            if n:
                not_normed = False  # set the not_normed boolean variable to True
            elif o:
                not_normed = False  # set the not_normed boolean variable to True

        normed_dates.append(cleaned_date)  # collect all normalized dates in the list normed_dates
        not_normed_list.append(not_normed)  # collect all boolean variable not_normed in the list not_normed_list

    # return the required objects
    return normed_dates