diff --git a/Day 9 homework - Sloetjes.md b/Day 9 homework - Sloetjes.md index ba1f59e..2730fa4 100644 --- a/Day 9 homework - Sloetjes.md +++ b/Day 9 homework - Sloetjes.md @@ -149,60 +149,70 @@ Python modules: 960 (94.96%) **10. Add a feature to the script which looks at `file` for each module, trims the filename to get the directory name, then prints out a histogram of how many modules are in each directory name. If you can't find a text histogram output library in anaconda's built-in modules, just print out the `*` character for each module.** ``` -import importlib.util -import os import sys +import os +from collections import defaultdict -def get_module_size(module_name): - spec = importlib.util.find_spec(module_name) - if spec is None: - return 0 - elif spec.origin.endswith(".py"): - filename = spec.origin - elif spec.cached: - filename = spec.cached - else: - return 0 - return os.stat(filename).st_size +def get_module_stats(): + byte_count = 0 + dso_count = 0 + py_count = 0 + module_dirs = defaultdict(int) -def get_module_sizes(): - sizes = {} - for module_name in sys.modules: - sizes[module_name] = get_module_size(module_name) - return sizes - -def summarize_modules(): - total_size = 0 - bytecode_size = 0 - dso_size = 0 - python_size = 0 - module_counts = {} - for module_name, size in get_module_sizes().items(): - if size == 0: + for name, module in sys.modules.items(): + if module is None: continue - total_size += size - if module_name.endswith("pyc"): - bytecode_size += size - elif hasattr(sys.modules[module_name], "__file__"): - file_name = sys.modules[module_name].__file__ - if file_name.endswith((".so", ".dll")): - dso_size += size - elif file_name.endswith(".py"): - python_size += size - directory = os.path.dirname(os.path.abspath(file_name)) - module_counts[directory] = module_counts.get(directory, 0) + 1 + filename = getattr(module, '__file__', None) + if not filename: + continue - print(f"Total module size: {total_size} bytes") - print(f"Bytecode modules: {bytecode_size/total_size*100:.2f}%") - print(f"DSO modules: {dso_size/total_size*100:.2f}%") - print(f"Python modules: {python_size/total_size*100:.2f}%") + if filename.endswith('.pyc') or filename.endswith('.pyo'): + byte_count += 1 + elif os.path.splitext(filename)[-1] in ('.so', '.dll'): + dso_count += 1 + else: + py_count += 1 - print("Module directory histogram:") - for directory, count in module_counts.items(): - print(f"{directory}: {'*' * count}") + module_dir = os.path.dirname(os.path.abspath(filename)) + module_dirs[module_dir] += 1 -if __name__ == "__main__": - summarize_modules() + total_count = byte_count + dso_count + py_count + + byte_percent = byte_count / total_count * 100 + dso_percent = dso_count / total_count * 100 + py_percent = py_count / total_count * 100 + + return { + 'bytecode': { + 'count': byte_count, + 'percent': byte_percent, + }, + 'DSO': { + 'count': dso_count, + 'percent': dso_percent, + }, + 'python': { + 'count': py_count, + 'percent': py_percent, + }, + 'total': total_count, + 'module_dirs': module_dirs, + } + +def print_module_stats(): + stats = get_module_stats() + + print(f'Total modules: {stats["total"]}') + print(f'Bytecode modules: {stats["bytecode"]["count"]} ({stats["bytecode"]["percent"]:.2f}%)') + print(f'DSO modules: {stats["DSO"]["count"]} ({stats["DSO"]["percent"]:.2f}%)') + print(f'Python modules: {stats["python"]["count"]} ({stats["python"]["percent"]:.2f}%)') + + print('\nModule directory histogram:') + for module_dir, count in sorted(stats['module_dirs'].items(), key=lambda x: x[1], reverse=True): + print(f'{module_dir}: {"*" * count}') + +if __name__ == '__main__': + print_module_stats() ```