Skip to content

Instantly share code, notes, and snippets.

@mcdickenson
Created September 11, 2017 21:06
Show Gist options
  • Save mcdickenson/9ef795e2c76cf3e7ff6d631c9bf6268e to your computer and use it in GitHub Desktop.
Save mcdickenson/9ef795e2c76cf3e7ff6d631c9bf6268e to your computer and use it in GitHub Desktop.
Compute histogram of method line count
import ast
import os
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from collections import defaultdict
def walk_dir(dirname, ext):
for root, dirs, files in os.walk(dirname):
for file in files:
if file.endswith(ext):
yield os.path.join(root, file)
def merge_dicts(dict1, dict2):
merged_keys = list(set(dict1.keys()) | set(dict2.keys()))
merged = {}
for k in merged_keys:
merged[k] = dict1.get(k, 0) + dict2.get(k, 0)
return merged
def count_function_lengths(pth):
# load file
f = open(pth, 'r')
# parse the AST of the file
t = ast.parse(f.read())
# count the length of the file
f.seek(0)
file_length = 0
for line in f:
file_length += 1
classes = [e for e in t.body if type(e) == ast.ClassDef]
funcs = [f for f in t.body if type(f) == ast.FunctionDef]
# get the starting line for each function and method
for kls in classes:
methods = [f for f in kls.body if type(f) == ast.FunctionDef]
funcs.extend(methods)
line_numbers = [f.lineno for f in funcs]
line_numbers.append(file_length)
# sort just to be sure
line_numbers = sorted(line_numbers)
# count function line lengths
counts = defaultdict(int)
# prepare histogram
for ix, ln in enumerate(line_numbers[0:-1]):
next_ln = line_numbers[ix+1]
function_length = next_ln - ln
counts[function_length] += 1
return counts
hist = {}
for filename in walk_dir('YOUR_PROJECT_DIRECTORY_HERE', '.py'):
counts = count_function_lengths(filename)
hist = merge_dicts(hist, counts)
# print hist
# plot the histogram
plt.bar(hist.keys(), hist.values(), width=1, color='b')
plt.savefig('hist.png')%
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment