diff --git a/Day 9 homework - Sloetjes.md b/Day 9 homework - Sloetjes.md index afc7e1d..8ec9e04 100644 --- a/Day 9 homework - Sloetjes.md +++ b/Day 9 homework - Sloetjes.md @@ -78,3 +78,89 @@ print(login) * In the code above, the name of the module is `"os"`, and the fromlist argument is not given, so the top-level package `"os"` is returned, which is equivalent to importing os with a regular import statement. * Therefore, the expression `__import__('os').getlogin()` is equivalent to `os.getlogin()`, but it dynamically imports the `os` module at runtime instead of using a regular import statement. + +**9. Using the functions you created above and `sys.modules`, create a module designed to be run from the command line (`python -m myscript.py`) that generates a report summarizing the module environment, and break down the percentages of bytecode modules, DSO modules (these have `file` end in `.so` or `.dll`), and normal python code. ** +``` +import sys +import os.path + +# Classify each module based on its __file__ attribute +bytecode_modules = [] +dso_modules = [] +source_modules = [] +for module_name, module in sys.modules.items(): + if module is None or not hasattr(module, '__file__'): + continue + filename = module.__file__ + if filename.endswith('.pyc'): + bytecode_modules.append(module_name) + elif filename.endswith(('.so', '.dll')): + dso_modules.append(module_name) + else: + source_modules.append(module_name) + +# Calculate the percentages of each module type +total_modules = len(sys.modules) +bytecode_percent = len(bytecode_modules +``` + +**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 + +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_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: + 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 + + 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}%") + + print("Module directory histogram:") + for directory, count in module_counts.items(): + print(f"{directory}: {'*' * count}") + +if __name__ == "__main__": + summarize_modules() +``` +