Compute the number of source lines of code or blocks used in an App Inventor 2 project?
是否有任何方法可以计算应用程序Inventor 2项目中使用的源代码行(SLOC)或块的数量?
对于那些碰巧安装了python 3+而不是2的用户+
找到这个
1 | return filter(os.path.isdir, [os.path.join(dir,f) for f in os.listdir(dir)]) |
替换为此
1 | return list(filter(os.path.isdir, [os.path.join(dir,f) for f in os.listdir(dir)])) |
我编写了一个python函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | from __future__ import print_function from __future__ import division import glob import ntpath import os import shutil import zipfile def unzip(source_filename, dest_dir): ''' Source: http://stackoverflow.com/questions/12886768/how-to-unzip-file-in-python-on-all-oses ''' with zipfile.ZipFile(source_filename) as zf: for member in zf.infolist(): # Path traversal defense copied from # http://hg.python.org/cpython/file/tip/Lib/http/server.py#l789 words = member.filename.split('/') path = dest_dir for word in words[:-1]: drive, word = os.path.splitdrive(word) head, word = os.path.split(word) if word in (os.curdir, os.pardir, ''): continue path = os.path.join(path, word) zf.extract(member, path) def list_subdirectories(dir): ''' Source: http://stackoverflow.com/questions/800197/get-all-of-the-immediate-subdirectories-in-python ''' return filter(os.path.isdir, [os.path.join(dir,f) for f in os.listdir(dir)]) def path_leaf(path): ''' Source: http://stackoverflow.com/questions/8384737/python-extract-file-name-from-path-no-matter-what-the-os-path-format ''' head, tail = ntpath.split(path) return tail or ntpath.basename(head) def bky_count_blocks(bky_filename): return open(bky_filename).read().count('<block ') def aia_count_blocks(aia_filename): ''' Count blocks in an AIA project ''' # unzip temp_folder = 'temp_aia' unzip(aia_filename, temp_folder) # Build path to .bky files, which contains all blocks for each screen of the AI2 project bky_files_path = os.path.join(temp_folder, 'src', 'appinventor', ) for i in range(6): bky_files_path = list_subdirectories(bky_files_path)[0] # walk inside... #print(bky_files_path) # Count total_blocks_count = 0 bky_filenames = glob.glob(os.path.join(bky_files_path, '*.bky')) for bky_filename in bky_filenames : bky_block_count = bky_count_blocks(bky_filename) print('Screen {0} contains {1} blocks'.format(path_leaf(bky_filename), bky_block_count)) total_blocks_count += bky_block_count print('The AIA project {0} contains {1} blocks spread across {2} screens.'.format(aia_filename, total_blocks_count, len(bky_filenames))) # Clean temp files shutil.rmtree(temp_folder) def main(): ''' This is the main function ''' aia_filename = 'test.aia' aia_count_blocks(aia_filename) if __name__ =="__main__": main() #cProfile.run('main()') # if you want to do some profiling |
输出:
1 2 3 4 5 6 7 8 9 | Screen address.bky contains 42 blocks Screen edit.bky contains 265 blocks Screen list.bky contains 233 blocks Screen logic.bky contains 954 blocks Screen plan.bky contains 70 blocks Screen table1.bky contains 206 blocks Screen table2.bky contains 157 blocks Screen Screen1.bky contains 16 blocks The AIA project test.aia contains 1943 blocks spread across 8 screens. |
可以有很多改进,例如避免对禁用的块进行计数、按块类型计数等。