Created
June 17, 2012 12:40
-
-
Save ychaouche/2944446 to your computer and use it in GitHub Desktop.
Tahar code inspector -> tells you if your python code is readable or not.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Hello, | |
Tahar is a little program (named after Inspecteur Tahar, a famous algerian movie character) that helps you keep your code minimal and clean. It warns you if one of your functions or methods code is longer than MAX_LENGTH lines (you can change the value of this macro in the begining of tahar's source code. Default is 25, this is the french EPITA/EPITECH's school standard for C functions). | |
You don'thave to copy tahar.py (or naive_tahar.py at the time of this writing) in the directory containing the modules you want to scan. You can just pass a dirctory or a list of python files with full access path. | |
Tahar should print something like this : | |
<execution trace> | |
chaouche@karabeela ~/PROG $ python naive_tahar.py autoguess.py hang.py | |
your app has 13 functions and methods in 2 classes across 2 modules | |
__init__ : 5 | |
difficulty_menu : 19 | |
enter_game : 25 | |
exit : 4 | |
get_random_word : 4 | |
run : 7 | |
welcome_screen : 7 | |
__init__ : 6 | |
fill : 3 | |
filled : 2 | |
auto_guess : 13 | |
base_guess : 11 | |
get_order : 3 | |
All your code should be readable. | |
chaouche@karabeela ~/PROG $ | |
</execution trace> | |
If all your functions are less than MAX_LENGTH lines, then Tahar tells you that your code should be readable. | |
This is a work in progress (still in alpha) and needs your code reviews. | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import inspect | |
import sys | |
import os | |
import dircache | |
MAX_LENGTH = 25 | |
def pretty_box(string): | |
print "##"+"#"*(len(string))+"##" | |
print "#",string,"#" | |
print "##"+"#"*(len(string))+"##" | |
def get_module(file_name): | |
# if it's a directory return all modules and submodules recursively | |
if os.path.isdir(file_name): | |
files = dircache.listdir(file_name) | |
return [get_module(one_file) for one_file in files] | |
if ".py" in file_name: | |
exploded_path = file_name.split(".py")[0].split(os.sep) | |
module_name = exploded_path[-1] | |
package = os.sep.join(exploded_path[:-1]) | |
## if package: | |
## sys.path.append(package) | |
## print "added %s to the path -filename was %s- " % (package,file_name) | |
if package not in sys.path: | |
sys.path.append(package) | |
print "added '%s' to the path" % (package) | |
print "importing module",module_name | |
return __import__(module_name) | |
def main(): | |
modules_names = [modulename.split(".py")[0] for modulename in sys.argv[1:]] | |
if not modules_names: | |
print "usage : %s source1.py [source2.py] ... " % sys.argv[0] | |
exit(0) | |
modules = [get_module(file_name) for file_name in sys.argv[1:]] | |
functions = map(lambda x:x[1],reduce(lambda x,y:x+y,[inspect.getmembers(module,inspect.isfunction) for module in modules])) | |
classes = map(lambda x:x[1],reduce(lambda x,y:x+y,[inspect.getmembers(module,inspect.isclass) for module in modules],[])) | |
methods = map(lambda x:x[1],reduce(lambda x,y:x+y,[inspect.getmembers(klass,inspect.ismethod) for klass in classes],[])) | |
loc = 0 | |
all_ok = True | |
padding = max([len(function.func_name) for function in methods+functions]) | |
pretty_box("Functions and methods lengths (in lines of code)") | |
for method in methods+functions : | |
lines = inspect.getsourcelines(method) | |
code_length = len(filter(lambda line:line.strip() and line.strip()[0] not in "#",inspect.getsourcelines(method)[0])) | |
loc += code_length | |
if code_length > MAX_LENGTH : | |
print "warning : method %s has %s lines" % (method.func_name, code_length) | |
all_ok = False | |
else: | |
print method.func_name.ljust(padding),":",code_length | |
if all_ok : | |
print "All your code should be readable. -max length is configured to %s-" % MAX_LENGTH | |
print "your app has %s lines of code, %s functions and methods in %s classes across %s modules" % (loc,len(methods)+len(functions),len(classes),len(modules)) | |
if __name__ == "__main__": | |
main() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment