Ejemplo n.º 1
0
def get_stats(paths):
    cc = CCHarvester(paths, cc_config)
    raw = RawHarvester(paths, cc_config)
    cc.run()
    raw.run()
    
    header = ['Filename', "SLOC", '#Functions', '#Intercepts', 'Max CC', 
              'Ave CC', 'Median CC', 'Min CC']
    data = {}
    for file_data in cc.results:
        filename, cc_results = file_data
        complexity = [x.complexity for x in cc_results if hasattr(x, 'is_method') and x.is_method]
        if len(complexity) > 0:
            print "Getting Complexity for:", filename
            data[filename] = {}
            data[filename]['Filename'] = filename
            data[filename]['Max CC'] = max(complexity)
            data[filename]['Min CC'] = min(complexity)
            data[filename]['Med CC'] = np.median(complexity)
            data[filename]['Ave CC'] = np.mean(complexity)
            data[filename]['#Functions'] = len(complexity)
        else:
            print "Skipping ", filename

    for file_data in raw.results:
        filename, results = file_data
        if filename in data:
            data[filename]['SLOC'] = results['sloc']
        else:
            print "Skipping ", filename

    return data
Ejemplo n.º 2
0
def test_raw_ipynb(log_mock):
    raw_cfg = cli.Config(**BASE_CONFIG_WITH_IPYNB.config_values)

    target = os.path.join(DIRNAME, 'data/example.ipynb')
    harvester = RawHarvester([DIRNAME], raw_cfg)
    out = json.loads(harvester.as_json())
    assert harvester.config.include_ipynb == True
    assert target in out
    assert out[target]['loc'] == 63
    assert out[target]['lloc'] == 37
    assert out[target]['sloc'] == 37
    assert out[target]['comments'] == 3
    assert out[target]['multi'] == 10
    assert out[target]['blank'] == 14
    assert out[target]['single_comments'] == 2
Ejemplo n.º 3
0
def raw(paths,
        exclude=None,
        ignore=None,
        summary=False,
        json=False,
        output_file=None):
    '''Analyze the given Python modules and compute raw metrics.

    :param paths: The paths where to find modules or packages to analyze. More
        than one path is allowed.
    :param -e, --exclude <str>: Exclude files only when their path matches one
        of these glob patterns. Usually needs quoting at the command line.
    :param -i, --ignore <str>: Ignore directories when their name matches one
        of these glob patterns: radon won't even descend into them. By default,
        hidden directories (starting with '.') are ignored.
    :param -s, --summary:  If given, at the end of the analysis display the
        summary of the gathered metrics. Default to False.
    :param -j, --json: Format results in JSON.
    :param -O, --output-file <str>: The output file (default to stdout).
    '''
    config = Config(
        exclude=exclude,
        ignore=ignore,
        summary=summary,
    )
    harvester = RawHarvester(paths, config)
    with outstream(output_file) as stream:
        log_result(harvester, json=json, stream=stream)
Ejemplo n.º 4
0
def test_raw_ipynb_cells(log_mock):
    raw_cfg = cli.Config(**BASE_CONFIG_WITH_IPYNB_AND_CELLS.config_values)

    target = os.path.join(DIRNAME, 'data/example.ipynb')
    harvester = RawHarvester([DIRNAME], raw_cfg)
    out = json.loads(harvester.as_json())
    cell_target = target + ":[3]"
    assert target in out
    assert cell_target in out
    assert out[cell_target]['loc'] == 52
    assert out[cell_target]['lloc'] == 27
    assert out[cell_target]['sloc'] == 27
    assert out[cell_target]['comments'] == 3
    assert out[cell_target]['multi'] == 10
    assert out[cell_target]['blank'] == 13
    assert out[cell_target]['single_comments'] == 2
Ejemplo n.º 5
0
def raw(paths,
        exclude=_cfg.get_value('exclude', str, None),
        ignore=_cfg.get_value('ignore', str, None),
        summary=False,
        json=False,
        output_file=_cfg.get_value('output_file', str, None),
        include_ipynb=_cfg.get_value('include_ipynb', bool, False),
        ipynb_cells=_cfg.get_value('ipynb_cells', bool, False),):
    '''Analyze the given Python modules and compute raw metrics.

    :param paths: The paths where to find modules or packages to analyze. More
        than one path is allowed.
    :param -e, --exclude <str>: Exclude files only when their path matches one
        of these glob patterns. Usually needs quoting at the command line.
    :param -i, --ignore <str>: Ignore directories when their name matches one
        of these glob patterns: radon won't even descend into them. By default,
        hidden directories (starting with '.') are ignored.
    :param -s, --summary:  If given, at the end of the analysis display the
        summary of the gathered metrics. Default to False.
    :param -j, --json: Format results in JSON.
    :param -O, --output-file <str>: The output file (default to stdout).
    :param --include-ipynb: Include IPython Notebook files
    :param --ipynb-cells: Include reports for individual IPYNB cells
    '''
    config = Config(
        exclude=exclude,
        ignore=ignore,
        summary=summary,
        include_ipynb=include_ipynb,
        ipynb_cells=ipynb_cells,
    )
    harvester = RawHarvester(paths, config)
    with outstream(output_file) as stream:
        log_result(harvester, json=json, stream=stream)
Ejemplo n.º 6
0
def obtem_loc() -> list:
    config = Config(exclude='', ignore='.*')
    repositorios = [f.path for f in scandir('./repositorios') if f.is_dir()]

    locs = []

    for repo in repositorios:
        resultados = RawHarvester([repo], config).results

        loc_repo = [r[1]['loc'] for r in list(resultados)]
        loc_total = sum(loc_repo)

        locs.append((repo, loc_total))

    return locs
Ejemplo n.º 7
0
def get_files_lines_of_code(paths, ignore):
    config = Config(
        exclude=ignore,
        ignore=ignore,
        summary=False,
    )
    harvester = RawHarvester(paths, config)

    data = []
    for filename, raw_data in harvester.results:
        if not raw_data:
            continue
        data.append((filename, raw_data['loc'],))

    sorted_scores = sorted(data, key=operator.itemgetter(1), reverse=True)
    return OrderedDict(sorted_scores)
Ejemplo n.º 8
0
def raw(code_path, results):
    """
    Compute raw metrics such as number of lines of code, documentation rate or complexity metrics

    :param code_path: Path to the source code
    :param results: Dictionary to which the results are appended.
    """

    # Lines
    h = RawHarvester([code_path], Config(exclude=None, ignore=None, summary=True))
    file_metrics = dict(h.results)

    # Maintainability
    h = MIHarvester([code_path],
                Config(min='A', max='C', multi=True, exclude=None, ignore=None, show=False, json=False,
                       sort=False))
    mi_metrics = dict(h.results)
    always_merger.merge(file_metrics, mi_metrics)

    # Create a summary for the total of the code
    summary = dict()
    summation_keys = ['loc', 'lloc', 'sloc', 'comments', 'multi', 'blank', 'single_comments']
    for k in summation_keys:
        summary[k] = sum([metrics[k] for metrics in file_metrics.values()])

    # Weighted average summaries
    averaging_keys = {'mi': 'sloc'}
    for key_index, weight_index in averaging_keys.items():
        if summary[weight_index] == 0.0:
            summary[weight_index] = 0.0
        else:
            summary[key_index] = sum([metrics[key_index] * metrics[weight_index] for metrics in file_metrics.values()]) / summary[weight_index]

    # Export results
    results[LINES_OF_CODE] = summary.get('lloc', 0)
    results[COMMENT_RATE] = (float(summary.get('comments', 0)) + float(summary.get('multi', 0))) / (max(1, float(summary.get('loc', 1))))
    results[MAINTAINABILITY_INDEX] = summary.get('mi', 0.0) / 100.0
Ejemplo n.º 9
0
def analyse(paths):

    #Setup the Configuration for each Harvester 
    config = Config(
        exclude=[],
        ignore=[],
        order=SCORE,
        no_assert= False,
        show_closures=False,
        min='A',
        max='F',
    )

    config2 = Config(
        exclude=[],
        ignore=[],
        by_function= False
    )

    config3 = Config(
        min= 'A',
        max= 'C',
        exclude=[],
        ignore=[],
        multi=True,
        show=True,
    )

    config4 = Config(
        exclude=[],
        ignore=[],
        summary=False,
        json=True,
    )
    


    """
    ----------------------
    Cyclomatic Complexity 
    ---------------------
    Cyclomatic Complexity corresponds to the number of decisions a block of code contains plus 1. 
    This number (also called McCabe number) is equal to the number of linearly independent paths through the code. 
    This number can be used as a guide when testing conditional logic in blocks.Radon analyzes the AST tree 
    of a Python program to compute Cyclomatic Complexity. Statements have the following effects on Cyclomatic Complexity:
    """
    
    h = CCHarvester(paths, config)
    ccResults = h._to_dicts()
    # print(ccResults)
    numOfFunctions = 0
    complexity = 0

    # for result in ccResults.values():
    #     numOfFunctions += 1
    #     complexity += result['complexity'] if isinstance(result, dict) else 0

    for path in paths:
        for i in ccResults.get(path, []):
            numOfFunctions += 1
            complexity += i["complexity"] if isinstance(i, dict) else 0

    cc = complexity/numOfFunctions if numOfFunctions != 0 else 0

    """
    -------------------
    Halstead's Metrics
    ------------------
    Halstead’s goal was to identify measurable properties of software, and the relations between them. 
    These numbers are statically computed from the source code: Effort, Bugs, Length, Difficulty, Time, Vocabulary , Volume
    """
    i = HCHarvester(paths, config2)
    hcResults = i._to_dicts()
  
    halsteadEffort = 0
    halsteadBugs = 0
    halsteadLength = 0 
    halsteadDifficulty = 0
    halsteadTime = 0
    halsteadVocabulary = 0 
    halsteadVolume = 0
    numberOfFiles = 0

    for result in hcResults.values():
        if 'total' in result:
            halsteadEffort += result["total"][9]
            halsteadBugs  += result["total"][11]
            halsteadLength  += result["total"][5]
            halsteadDifficulty += result["total"][8]
            halsteadTime += result["total"][10]
            halsteadVocabulary += result["total"][4]
            halsteadVolume += result["total"][7]
        numberOfFiles += 1

    avgHalsteadEffort = halsteadEffort/numberOfFiles
    avgHalsteadBugs = halsteadBugs/numberOfFiles
    avgHalsteadLength = halsteadLength /numberOfFiles
    avgHalsteadDifficulty = halsteadDifficulty/numberOfFiles
    avgHalsteadTime = halsteadTime/numberOfFiles
    avgHalsteadVocabulary = halsteadVocabulary/numberOfFiles
    avgHalsteadVolume = halsteadVolume/numberOfFiles

    
    """
    ---------------------------------------
    MI Harvester for Maintainability index
    --------------------------------------
    Maintainability Index is a software metric which measures how maintainable (easy to support and change)
    the source code is. The maintainability index is calculated as a factored formula consisting of SLOC (Source Lines Of Code),
    Cyclomatic Complexity and Halstead volume. It is used in several automated software metric tools, including the Microsoft 
    Visual Studio 2010 development environment, which uses a shifted scale (0 to 100) derivative.
    """
    j = MIHarvester(paths, config3)
    miResults = dict(j.filtered_results)

    miVal = 0 
    numOfFiles = 0
    for result in miResults.values():
        if 'mi' in result:
            miVal += result["mi"] 
        numOfFiles += 1

    mi = miVal/numOfFiles
    


    """
    ------------
    Raw Metrics
    -----------
    The following are the definitions employed by Radon:
     - LOC: The total number of lines of code. It does not necessarily correspond to the number of lines in the file.
     - LLOC: The number of logical lines of code. Every logical line of code contains exactly one statement.
     - SLOC: The number of source lines of code - not necessarily corresponding to the LLOC. [sloc]
     - Comments: The number of comment lines. Multi-line strings are not counted as comment since, to the Python interpreter, they are just strings.
     - Multi: The number of lines which represent multi-line strings.  [multi] 
     - Blanks: The number of blank lines (or whitespace-only ones).  [blank]
    """
    k = RawHarvester(paths, config4)
    rawResults = (dict(k.results))

    comments = 0
    lloc = 0
    loc = 0
    for result in rawResults.values():
        if 'comments' in result:
            comments += result['comments']
        if 'lloc' in result:
            lloc += result['lloc']
        if 'loc' in result:
            loc += result['loc']


    data = {
        "numberOfFiles" : len(paths),
        "numberOfLines" : loc,
        "numberOfLogicalLines" : lloc, 
        "numberOfComments" : comments, 
        "cyclomaticComplexity" : cc, 
        "maintainabilityIndex" : mi,
        "halsteadEffort" : avgHalsteadEffort,
        "halsteadBugs" : avgHalsteadBugs,
        "halsteadLength" :avgHalsteadLength,
        "halsteadDifficulty" : avgHalsteadDifficulty,
        "halsteadTime" : avgHalsteadTime, 
        "halsteadVocabulary" : avgHalsteadVocabulary, 
        "halsteadVolume" : avgHalsteadVolume
    }

    return data