def collect_metrics(code): d = {key:None for key in keys} content = h_visit(code) d["uniq_Op"] = content.h1 d["uniq_Opnd"] = content.h2 d["total_Op"] = content.N1 d["total_Opnd"] = content.N2 d["n"] = float(content.N1) + float(content.N2) d["volume"] = content.volume d["prolength"] = content.length d["difficulty"] = content.difficulty d["effort"] = content.effort d["bug"] = content.bugs d["time_est"] = content.time content = analyze(code) d["loc"] = content.loc d["lOCode"] = content.loc d["lOComment"] = content.comments d["lOBlank"] = content.blank d["lOCodeAndComment"] = float(content.loc) + float(content.comments) content = mi_parameters(code) d["cc"] = content[1] return d
def check_code_complexity(lab_answer, lab_key): result = {} source = inspect.getsource(lab_answer) h = rm.h_visit(source) hm = rm.h_visit_ast(h) v = analyze(source) return result
def analyse_halstead_metrics(iface, code): metrics = h_visit(code) iface.report_metric("halstead_volume", metrics.volume) if metrics.volume > 8000: iface.report_violation("halstead_volume_above_8000", "Halstead Volume of " + str(metrics.volume)) iface.report_metric("halstead_time", metrics.time) iface.report_metric("halstead_bugs", metrics.bugs) if metrics.bugs > 2: iface.report_violation("halstead_bugs_above_2", "Halstead Bugs of " + str(metrics.bugs)) return metrics.volume
def radon_test(f): filename = 'a1/a1_solution_' + f + '.py' with open(filename) as file: source = file.read() cv = ComplexityVisitor.from_code(source) res = sorted_results(cv.functions + cv.classes, order=LINES) output = {} for r in res: # print(f'Function: {r.name}, CC: {r.complexity}') output['CC'] = r.complexity res = analyze(source) # pprint(res) basic = {'loc': res[0], 'lloc': res[1], 'sloc': res[2], 'comments': res[3], 'multi': res[4], 'blank': res[5], 'single_comment': res[6]} output['Lines'] = basic config = Config(min='A', max='F', exclude=None, ignore=None, no_assert=False, show_closures=False, order=LINES) ch = CCHarvester([filename], config) res = ch.results x = json.loads(ch.as_json()) # pprint(x) res = h_visit(source) hals = {'h1': res[0], 'h2': res[1], 'N1': res[2], 'N2': res[3], 'vocabulary': res[4], 'length': res[5], 'calculated_length': res[6], 'volume': res[7], 'difficulty': res[8], 'effort': res[9], 'time': res[10], 'bugs': res[11]} output['Halstead'] = hals pprint({f: output})
def pickle_func(name): with open(name) as f: # Return a tuple because pickle is f*****g stupid. try: res = h_visit(f.read()) except SyntaxError: print("Ign: Invalid syntax in '{}'".format(name)) return None total = tuple(res.total) functions = [(name, tuple(report)) for (name, report) in res.functions] return (total, functions)
def get_code_metrics(sort_name): with open(f"sort_algorithms/{sort_name}/code.txt", "r") as f: code = "".join(f.readlines()) metricas = metrics.h_visit(code) mi_parameters = metrics.mi_parameters(code) analize = raw.analyze(code) return OrderedDict({ "Nome": sort_name, "Número de linhas de código": analize.lloc, "Número de operadores": metricas.total.N1, "Número de operandos": metricas.total.N2, "Dificuldade": metricas.total.difficulty, "Esforço": metricas.total.effort, "Complexidade ciclomática": mi_parameters[1], })
def analyse(self): output = {} cv = ComplexityVisitor.from_code(self._source) res = sorted_results(cv.functions + cv.classes, order=LINES) # should be one result, since giving one function # if len(res) > 1: # raise ValueError('Complexity Analysis returned multiple results') output['cc'] = res[0].complexity res = analyze(self._source) lines_comments = dict(res._asdict()) output.update(lines_comments) res = h_visit(self._source) hals = dict(res._asdict()) output.update(hals) self._res = output
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 halstead(func_str,lang="python"): if lang=="python": vis = h_visit(func_str) # print(vis) res = {} keys = ["h1", "h2", "N1", "N2", "vocabulary", "length", "calculated_length", "volume", "Difficulty", "effort", "time", "bugs"] """ vis[0] returns for combined for multiple functions, ==> the total report """ # print((vis[0], "\n", type(vis[0])) value = vis[0] res = dict(zip(keys, value)) return res """ vis[1] contains list of each func separately """ # res={} # for name, value in vis[1]: # # print(name, value[0],len(value)) # res=dict(zip(keys, value)) # print(res) else: with open('code.txt', 'w') as f: # web_browsers = ['Firefox\n', 'Chrome\n', 'Edge\n'] f.writelines(func_str) os.system("g++ halstead.cpp") time.sleep(2) out = subprocess.Popen(['./a.out'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) stdout,stderr = out.communicate() os.system("rm code.txt ./a.out") # print(type(stdout),stdout,"\n",stderr) lines = stdout.decode("utf-8") #stdout is of types bytes, hence the conversion lines=lines.split('\n') halstead={} for i in lines: i=i.split(":") # print(i) if i[0] in ['n1','n2','N1','N2']: halstead[i[0]] = int(i[1]) else: halstead[i[0]]=float(i[1]) #print(halstead) return halstead
async def analyze(self, tup: NativeBlobMetricInput) -> Iterable[Metric]: try: h_data = h_visit(tup.blob.data.decode()) except (SyntaxError, UnicodeDecodeError): return [] # TODO get an error output? result = [ Metric( self.name, fn_data._asdict(), False, ObjectIdentifier(tup.blob.id, tup.path), fn_name, ) for fn_name, fn_data in h_data.functions ] result.append( Metric( self.name, h_data.total._asdict(), False, ObjectIdentifier(tup.blob.id, tup.path), ) ) return result
def generateHalsteadMetrics(self): hl = h_visit(self.sourceFile) return hl
def gobble(self, fobj): """Analyze the content of the file object.""" code = fobj.read() return h_visit(code)
for nBeat in range(0, len(bts)): hBeatInTest = bts[nBeat] distancia = bts[0][nBeat] indRPeak = Indpks[nBeat] print(distancia > (sts[1] + 0.5 * sts[2])) if ((np.max(hBeatInTest) > (1.5 * sts[4]) and (np.min(hBeatInTest) < (1.5 * sts[3]))) or (distancia > (sts[1] + 0.5*sts[2])) or (np.argmax(hBeatInTest) != indRPeak)): outlierBeats.append(nBeat + TemplatePks * n) print(outlierBeats)""" #execute the h_visit method, which gives you a Halstead module with all the complexity measures visitor = h_visit(dedent(code)) """ visitor.N1 = 15 visitor.N2 = 31 visitor.bugs = 0.07865 visitor.calulated_length = 154.26 visitor.difficulty = 3.875 visitor.effort = 914.29 visitor.h1 = 7 visitor.h2 = 28 visitor.length = 46 visitor.time = 50.79 visitor.vocabulary = 35 visitor.volume = 235.95 """ """ Visit the AST node using the :class:`~radon.visitors.HalsteadVisitor`
def get_halstead_for_file(filepath): print("Halstead metric") with _open(filepath) as fobj: halstead = h_visit(fobj.read()) return halstead
def halstead_metrics(input_file): with open(input_file, 'r') as file: return h_visit(file.read()).total
def __get_code_metrics(codigo: str): """ Recupera as métricas de um código Python. McCabe's (Complexidade) - complexity: Complexidade Total - n_classes: Quantidade de Classes - n_functions: Quantidade de Funções Métricas Brutas (Código) - loc: Número Total de Linhas - lloc: Número de Linhas Lógicas de Código - sloc: Número de Linhas de Código - comments: Número de Comentários - single_comments: Número de Comentários Simples - multilines: Número de Multi-line Strings - blank_lines: Número de Linhas em Branco Halstead (Métricas de SW) - h1: Número de Operadores Distintos - h2: Número de Operandos Distintos - N1: Número Total de Operadores - N2: Número Total de Operandos - vocabulary: Vocabulário (h = h1 + h2) - length: Tamanho (N = N1 + N2) - calculated_length: Tamanho Calculado (h1 * log2(h1) + h2 * log2(h2)) - volume: Volume (V = N * log2(h)) - difficulty: Dificuldade (D = h1/2 * N2/h2) - effort: Esforço (E = D * V) - time: Tempo (T = E / 18 segundos) - bugs: Bugs (B = V / 3000), estivativa de erros na implementação :param path: Caminho absoluto para o arquivo de código fonte (.py). :type path: str :return: As métricas que puderam ser extraídas do código. """ metricas = Metricas() try: v = ComplexityVisitor.from_code(codigo) metricas.complexity = v.complexity metricas.n_functions = len(v.functions) metricas.n_classes = len(v.functions) except Exception as e: pass try: a = analyze(codigo) metricas.loc = a.loc metricas.lloc = a.lloc metricas.sloc = a.sloc metricas.blank_lines = a.blank metricas.multilines = a.multi metricas.comments = a.comments metricas.single_comments = a.single_comments except Exception as e: pass try: h = h_visit(codigo) metricas.h1 = h.total.h1 metricas.h2 = h.total.h2 metricas.N1 = h.total.N1 metricas.N2 = h.total.N2 metricas.h = h.total.vocabulary metricas.N = h.total.length metricas.calculated_N = h.total.calculated_length metricas.volume = h.total.volume metricas.difficulty = h.total.difficulty metricas.effort = h.total.effort metricas.bugs = h.total.bugs metricas.time = h.total.time except Exception as e: pass return metricas
def HalsteadClassical(code, pythonFile): """ Accepts the code in comments and the pythonFile that runs the corresponding code to search for all operators. The first stage, will use the radon.visitor command to find all methods that correspond as operators in the python module. The second phase will search for operators and operands as functions, in which the function name is a operators and its arguments are operands. It searches for functions inside functions. Note that some functions might not be found if the code uses some previous simplification of the module, like: import numpy as np: np.percentile --> might not be defined as function from numpy import percentile: percentile --> will be set as function for sure """ """ * h1: the number of distinct operators * h2: the number of distinct operands * N1: the total number of operators * N2: the total number of operands """ #For typical operators in the script dedent = lambda code: textwrap.dedent(code).strip() visitor = h_visit(dedent(code)) oprt = visitor[0] oprd = visitor[1] Toprt = visitor[2] Toprd = visitor[3] TMoperators = [] TMoperands = [] #Find all function candidates functions = rx.findall(r'(\w+)\(', code) #Find the true functions and arguments for name, data in inspect.getmembers(pythonFile, inspect.isfunction): if (name in functions): TMoperators.append(name) # search for all arguments of the named function: print('%s :' % name) a = rx.findall(name + r'\(.*?\)', code) #look for specific arguments for s in a: #Find arguments that comes after a comma, inclusive if misinterpretate an argument with a # interval: peaks(a, b, c[0, 10]) --> ['b' , 'c[0', '10]'] b = rx.findall(r', (.*?[\[\]\)])', s) # finds all first arguments: peaks(a, b, c[0, 10]) --> ['a'] c = rx.findall(name + r'\((.*?)[,\)\[]', s) TMoperands += c #searches in b which are the correct arguments: if b: for ss in b: print(ss) #['b' , 'c[0', '10]'] if ']' not in ss: ss = rx.findall(r'(.*?)[\[\)]', ss) TMoperands += ss #['b' , 'c[0', '10]'] --> ['b', 'c'] Moperands = np.unique(TMoperands) Moperators = np.unique(TMoperators) print("Total Operands: ") print(TMoperands) print("Total Operators: ") print(TMoperators) print("unique operands: ") print(Moperands) print("unique operators: ") print(Moperators) oprt += np.size(Moperators) oprd += np.size(Moperands) Toprt += np.size(TMoperators) Toprd += np.size(TMoperands) voc = Vocabulary(oprt, oprd) lgt = Length(Toprt, Toprd) entropy = EntropyLength(oprt, oprd) vol = Volume(lgt, voc) dif = Difficulty(oprt, oprd, Toprd) eff = Effort(vol, dif) return oprt, oprd, Toprt, Toprd, voc, lgt, entropy, vol, dif, eff
from radon.metrics import h_visit import sys ffile = open(str(sys.argv[1]), 'r') data = ffile.read() h = h_visit(data) print str( sys.argv[1] ), h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7], h[8], h[9], h[10], h[11]