<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:

def getClassTypeMonthlyData(year=None, series=None, typeLimit=None):
    '''
    To break out by class type and month simultaneously, get data for each
    series and aggregate by class type.
    '''

    # If no year specified, report current year to date.
    if not year:
        year = timezone.now().year

    role_list = DanceRole.objects.distinct()

    # Report data on all students registered unless otherwise specified
    if series not in ['registrations','studenthours'] and series not in [x.pluralName for x in role_list]:
        series = 'registrations'

    when_all = {
        'eventregistration__dropIn': False,
        'eventregistration__cancelled': False,
    }

    annotations = {'registrations': Sum(Case(When(Q(**when_all),then=1),output_field=FloatField()))}

    for this_role in role_list:
        annotations[this_role.pluralName] = Sum(Case(When(Q(Q(**when_all) & Q(eventregistration__role=this_role)),then=1),output_field=FloatField()))

    series_counts = Series.objects.filter(year=year).annotate(**annotations).annotate(studenthours=F('duration') * F('registrations')).select_related('classDescription__danceTypeLevel__danceType','classDescription__danceTypeLevel')

    # If no limit specified on number of types, then do not aggregate dance types.
    # Otherwise, report the typeLimit most common types individually, and report all
    # others as other.  This gets tuples of names and counts
    dance_type_counts = [(dance_type,count) for dance_type,count in Counter([x.classDescription.danceTypeLevel for x in series_counts]).items()]
    dance_type_counts.sort(key=lambda k: k[1],reverse=True)

    if typeLimit:
        dance_types = [x[0] for x in dance_type_counts[:typeLimit]]
    else:
        dance_types = [x[0] for x in dance_type_counts]

    results = []

    # Month by month, calculate the result data
    for month in range(1,13):
        this_month_result = {
            'month': month,
            'month_name': month_name[month],
        }
        for dance_type in dance_types:
            this_month_result[dance_type.__str__()] = \
                series_counts.filter(classDescription__danceTypeLevel=dance_type,month=month).aggregate(Sum(series))['%s__sum' % series]

        if typeLimit:
            this_month_result['Other'] = \
                series_counts.filter(month=month).exclude(classDescription__danceTypeLevel__in=dance_types).aggregate(Sum(series))['%s__sum' % series]

        results.append(this_month_result)

    # Now get totals
    totals_result = {
        'month': 'Totals',
        'month_name': 'totals',
    }

    for dance_type in dance_types:
        totals_result[dance_type.__str__()] = \
            series_counts.filter(classDescription__danceTypeLevel=dance_type).aggregate(Sum(series))['%s__sum' % series]

    if typeLimit:
        totals_result['Other'] = \
            series_counts.exclude(classDescription__danceTypeLevel__in=dance_types).aggregate(Sum(series))['%s__sum' % series]

    results.append(totals_result)

    return results