def compute_complexity(source): result = [] blocks = cc_visit(source) mix_path = mi_visit(source, True) for func in blocks: result.append(func.name + ": Rank:" + cc_rank(func.complexity)) return result
def mi(multi=True, exclude=None, show=False, *paths): '''Analyze the given Python modules and compute the Maintainability Index. The maintainability index (MI) is a compound metric, with the primary aim of to determine how easy it will be to maintain a particular body of code. :param multi: Whether or not to count multiline strings as comments. Most of the time this is safe since multiline strings are used as functions docstrings, but one should be aware that their use is not limited to that and sometimes it would be wrong to count them as comment lines. :param paths: The modules or packages to analyze. ''' for name in iter_filenames(paths, exclude): with open(name) as fobj: try: result = mi_visit(fobj.read(), multi) except Exception as e: log('{0}\n{1}ERROR: {2}', name, ' ' * 4, str(e)) continue except KeyboardInterrupt: log(name) return rank = mi_rank(result) color = MI_RANKS[rank] to_show = '' if show: to_show = ' ({0:.2f})'.format(result) log('{0} - {1}{2}{3}{4}', name, color, rank, to_show, RESET)
def mi(multi=True, exclude=None, ignore=None, show=False, *paths): '''Analyze the given Python modules and compute the Maintainability Index. The maintainability index (MI) is a compound metric, with the primary aim being to determine how easy it will be to maintain a particular body of code. :param -e, --exclude <str>: Comma separated list of patterns to exclude. :param -i, --ignore <str>: Comma separated list of patterns to ignore. Radon won't even descend into those directories. :param -m, --multi: If given, multiline strings are counted as comments. :param -s, --show: If given, the actual MI value is shown in results. :param paths: The modules or packages to analyze. ''' for name in iter_filenames(paths, exclude, ignore): with open(name) as fobj: try: result = mi_visit(fobj.read(), multi) except Exception as e: log(name, indent=1) log_error(e, indent=1) continue except KeyboardInterrupt: log(name) return rank = mi_rank(result) color = MI_RANKS[rank] to_show = '' if not show else ' ({0:.2f})'.format(result) log('{0} - {1}{2}{3}{4}', name, color, rank, to_show, RESET)
def maintainability(self): logging.info("Maintainability analysis") try: self.maintain = mi_visit(self.__code,True) return self.maintain except SyntaxError: logging.error("Syntax Error in analyzed code") print("Syntax Error in analyzed code")
def maintainability(self): logging.info("Maintainability analysis") try: self.maintain = mi_visit(self.__code, True) return self.maintain except SyntaxError: logging.error("Syntax Error in analyzed code") print("Syntax Error in analyzed code")
def compute_complexity(source): result = [] # get complexity blocks blocks = cc_visit(source) # get MI score mi = mi_visit(source, True) for slave in blocks: result.append(slave.name + "-Rank:" + cc_rank(slave.complexity)) return result
def compute_complexity(source): result = [] # get cc blocks blocks = cc_visit(source) # get MI score mi = mi_visit(source, True) for func in blocks: result.append(func.name + "- CC Rank:" + cc_rank(func.complexity)) return result
async def analyze(self, tup: NativeBlobMetricInput) -> Iterable[Metric]: try: mi_data = mi_visit(tup.blob.data.decode(), multi=True) except (SyntaxError, UnicodeDecodeError): return [] # TODO get an error output? result = [ Metric( self.name, float(mi_data), False, ObjectIdentifier(tup.blob.id, tup.path), ) ] return result
def evaluate_code(kata_test, kata_implementation, kata_path): """ Evaluate the code resulting from executing the kata_implementation stared at the given path :param kata_test: the test to pass :param kata_implementation: the kata implementation :param kata_path: the kata script """ time_consumption = timeit.timeit(lambda: kata_test(kata_implementation), number=10000) with open(kata_path, "r") as kata_file: kata_code = kata_file.read() mantainability_index = mi_visit(kata_code, False) cyclomatic_complexity = cc_visit(kata_code)[0].complexity return { "time": time_consumption, "mi": mantainability_index, "cc": cyclomatic_complexity }
def generate_radon_metrics(code_input): radon_metrics = make_default_radon_metrics() try: # raw metrics raw_metrics = analyze(code_input) radon_metrics['loc'] = raw_metrics.loc radon_metrics['lloc'] = raw_metrics.lloc radon_metrics['sloc'] = raw_metrics.sloc radon_metrics['comments'] = raw_metrics.comments radon_metrics['multi'] = raw_metrics.multi radon_metrics['single_comments'] = raw_metrics.single_comments # cyclomatic complexity cc = ComplexityVisitor.from_code(code_input) radon_metrics['function_num'] = len(cc.functions) total_function_complexity = 0.0 for fun in cc.functions: total_function_complexity += fun.complexity radon_metrics['total_function_complexity'] = total_function_complexity radon_metrics['radon_functions_complexity'] = cc.functions_complexity # calculate based on AST tree v = h_visit_ast(h_visit(code_input)) radon_metrics['h1'] = v.h1 radon_metrics['h2'] = v.h2 radon_metrics['N1'] = v.N1 radon_metrics['N2'] = v.N2 radon_metrics['vocabulary'] = v.vocabulary radon_metrics['length'] = v.length radon_metrics['calculated_length'] = v.calculated_length radon_metrics['volume'] = v.volume radon_metrics['difficulty'] = v.difficulty radon_metrics['effort'] = v.effort radon_metrics['time'] = v.time radon_metrics['bugs'] = v.bugs # Maintainability Index (MI) based on ## the Halstead Volume, the Cyclomatic Complexity, the SLOC number and the number of comment lines mi = mi_visit(code_input, multi=True) radon_metrics['Maintainability_Index'] = mi return radon_metrics except: return radon_metrics
def program_complexity(projno, funcno): """ Builds and returns two dictionaries mapping filename:cc and filename:mi. """ cc_dic = {} mi_dic = {} path = os.getcwd() + \ "/extracted_files/proj{0}_func{1}/".format(projno, funcno) for fname in os.listdir(path): if fname[-4:] == '.pyc': continue try: f = open(path + fname) content = f.read() blocks = cc_visit(content) mi = mi_visit(content, True) cc_dic[fname] = blocks[0].complexity mi_dic[fname] = mi f.close() except: print " ERROR: cannot find file " + path + fname return cc_dic, mi_dic
param_dict = OrderedDict() print('1. METHODS OF PROJECT FILES SORTED BY CYCLOMATIC COMPLEXITY') for filename in iter_filenames(['.']): file_methods = [] file_complexities = [] methods_dictionary = OrderedDict() with open(filename) as fobj: source = fobj.read() # get cc blocks blocks = cc_visit(source) # get MI score mi = mi_visit(source, True) mi_dict[mi] = filename # get raw metrics raw = analyze(source) hal_vol, complexity, logic_lines, com_lines = mi_parameters(source) param_dict[complexity] = (complexity, filename, hal_vol, logic_lines, com_lines) # get metrics for each file file_complexity = sorted_results(blocks) try: file_methods.append(re.findall('(?<=.Function\(name=\')[^\']' '*(?=\')', str(file_complexity))) file_complexities.append(re.findall('(?<=.complexity=)\d*',
def gobble(self, fobj): '''Analyze the content of the file object.''' mi = mi_visit(fobj.read(), self.config.multi) rank = mi_rank(mi) return {'mi': mi, 'rank': rank}
from radon.complexity import cc_rank, cc_visit from radon.metrics import mi_visit, mi_rank from radon.raw import analyze # Metrics that are usable: Maintainability Index teststring = (''' ` ''') def my_function(): print("Hello from a function") def factorial(n): if n < 2: return 1 return n * factorial(n - 1) #print (analyze(teststring)) #print (cc_visit(teststring)) mivalue = (mi_visit(teststring, 0)) print(mivalue) print(mi_rank(mivalue))
def gobble(self, fobj): '''Analyze the content of the file object.''' return {'mi': mi_visit(fobj.read(), self.config.multi)}
def maintainabilityIndex(code): miScore = mi_visit(code, True) miRank = mi_rank(miScore) return [miScore, miRank]