from collections import defaultdict

def docstrings(items):
    
    n_docstrings = defaultdict(lambda : 0)
    n_objects = defaultdict(lambda :0)
    total_docstring_length = defaultdict(lambda :0)

    for item in items:
        for key,value in item['total_docstring_length'].items():
            total_docstring_length[key] += value
        for key,value in item['n_objects'].items():
            n_objects[key] += value
        for key,value in item['n_docstrings'].items():
            n_docstrings[key] += value

    return {
        'total_docstring_length' : dict(total_docstring_length),
        'n_objects' : dict(n_objects),
        'n_docstrings' : dict(n_docstrings),
    }


def functions(items):

    n = 0
    total_number_of_lines = 0
    total_cyclomatic_complexity = 0
    naming_conventions = defaultdict(lambda : 0)
    cyclomatic_complexity_distribution = defaultdict(lambda : 0)

    for item in items:

        n+=item['n']
        total_number_of_lines+= item['total_number_of_lines']
        total_cyclomatic_complexity+= item['total_cyclomatic_complexity']

        for key,value in item['cyclomatic_complexity_distribution'].items():
            cyclomatic_complexity_distribution[key]+=value

        for key,value in item['naming_conventions'].items():
            naming_conventions[key]+=value

    if n == 0:
        average_number_of_lines = 0
        average_cyclomatic_complexity = 0
    else:
        average_number_of_lines = total_number_of_lines/float(n)
        average_cyclomatic_complexity = total_cyclomatic_complexity/float(n)
        
    return {
        'n_functions' : n,
        'average_cyclomatic_complexity' : average_cyclomatic_complexity,
        'total_cyclomatic_complexity' : total_cyclomatic_complexity,
        'cyclomatic_complexity_distribution' : dict(cyclomatic_complexity_distribution),
        'average_number_of_lines' : average_number_of_lines,
        'total_number_of_lines' : total_number_of_lines,
        'naming_conventions' : dict(naming_conventions),
        }

def variables(items):
    total_length = 0
    naming_conventions = defaultdict(lambda :0)
    n = 0

    for item in items:
        n+=item['n']
        total_length+= item['n']*item['average_length']
        for key,value in item['naming_conventions'].items():
            naming_conventions[key]+=value

    if n == 0:
        average_length = 0
    else:
        average_length = total_length/float(n)

    return {
        'average_length' : average_length,
        'naming_conventions' : dict(naming_conventions),
        'n' : n,
        }

def classes(items):

    n = 0
    occurences = {}
    number_of_lines = 0
    total_number_of_lines = 0
    total_number_of_functions = 0
    total_cyclomatic_complexity = 0
    naming_conventions = defaultdict(lambda : 0)
    cyclomatic_complexity_distribution = defaultdict(lambda : 0)

    for item in items:

        n += item['n']
        total_number_of_lines+= item['total_number_of_lines']
        total_number_of_functions += item['total_number_of_functions']
        total_cyclomatic_complexity+= item['total_cyclomatic_complexity']

        for key,value in item['cyclomatic_complexity_distribution'].items():
            cyclomatic_complexity_distribution[key]+=value

        for key,value in item['naming_conventions'].items():
            naming_conventions[key]+=value

    if n == 0:
        average_number_of_lines = 0
        average_number_of_functions = 0
        average_cyclomatic_complexity = 0
    else:
        average_number_of_lines = total_number_of_lines/float(n)
        average_number_of_functions = total_number_of_functions/float(n)
        average_cyclomatic_complexity = total_cyclomatic_complexity/float(n)

    return {
        'n' : n,
        'average_cyclomatic_complexity' : average_cyclomatic_complexity,
        'total_cyclomatic_complexity' : total_cyclomatic_complexity,
        'cyclomatic_complexity_distribution' : dict(cyclomatic_complexity_distribution),
        'average_number_of_lines' : average_number_of_lines,
        'total_number_of_lines' : total_number_of_lines,
        'average_number_of_functions' : average_number_of_functions,
        'total_number_of_functions' : total_number_of_functions,
        'naming_conventions' : dict(naming_conventions)
        }
