AST finished
This commit is contained in:
parent
a5a657250d
commit
a62255e30d
290
AST Files/dependency_graph.dot
Normal file
290
AST Files/dependency_graph.dot
Normal file
@ -0,0 +1,290 @@
|
||||
digraph G {
|
||||
rankdir=LR;
|
||||
node [shape=box, style=filled, fillcolor=lightblue];
|
||||
"run_analysis_pipeline" -> "remove_nans" [color=red];
|
||||
"run_analysis_pipeline" -> "remove_outliers" [color=red];
|
||||
"run_analysis_pipeline" -> "full_report" [color=red];
|
||||
"run_analysis_pipeline" -> "normality_test" [color=red];
|
||||
"run_analysis_pipeline" -> "add_descriptive" [color=red];
|
||||
"run_analysis_pipeline" -> "add_hypothesis" [color=red];
|
||||
"run_analysis_pipeline" -> "to_dict" [color=red];
|
||||
"DataCleaner" -> "u" [color=gray];
|
||||
"DataCleaner" -> "c" [color=gray];
|
||||
"run_analysis_pipeline" -> "remove_nans" [color=red];
|
||||
"run_analysis_pipeline" -> "remove_outliers" [color=red];
|
||||
"run_analysis_pipeline" -> "full_report" [color=red];
|
||||
"run_analysis_pipeline" -> "normality_test" [color=red];
|
||||
"run_analysis_pipeline" -> "add_descriptive" [color=red];
|
||||
"run_analysis_pipeline" -> "add_hypothesis" [color=red];
|
||||
"run_analysis_pipeline" -> "to_dict" [color=red];
|
||||
"DataCleaner" -> "u" [color=gray];
|
||||
"DataCleaner" -> "c" [color=gray];
|
||||
"run_analysis_pipeline" -> "remove_nans" [color=red];
|
||||
"run_analysis_pipeline" -> "remove_outliers" [color=red];
|
||||
"run_analysis_pipeline" -> "full_report" [color=red];
|
||||
"run_analysis_pipeline" -> "normality_test" [color=red];
|
||||
"run_analysis_pipeline" -> "add_descriptive" [color=red];
|
||||
"run_analysis_pipeline" -> "add_hypothesis" [color=red];
|
||||
"run_analysis_pipeline" -> "to_dict" [color=red];
|
||||
"DataCleaner" -> "u" [color=gray];
|
||||
"DataCleaner" -> "c" [color=gray];
|
||||
"DataCleaner" -> "remove_outliers" [color=black];
|
||||
"run_analysis_pipeline" -> "remove_nans" [color=red];
|
||||
"run_analysis_pipeline" -> "remove_outliers" [color=red];
|
||||
"run_analysis_pipeline" -> "full_report" [color=red];
|
||||
"run_analysis_pipeline" -> "normality_test" [color=red];
|
||||
"run_analysis_pipeline" -> "add_descriptive" [color=red];
|
||||
"run_analysis_pipeline" -> "add_hypothesis" [color=red];
|
||||
"run_analysis_pipeline" -> "to_dict" [color=red];
|
||||
"DataCleaner" -> "u" [color=gray];
|
||||
"DataCleaner" -> "c" [color=gray];
|
||||
"run_analysis_pipeline" -> "remove_nans" [color=red];
|
||||
"run_analysis_pipeline" -> "remove_outliers" [color=red];
|
||||
"run_analysis_pipeline" -> "full_report" [color=red];
|
||||
"run_analysis_pipeline" -> "normality_test" [color=red];
|
||||
"run_analysis_pipeline" -> "add_descriptive" [color=red];
|
||||
"run_analysis_pipeline" -> "add_hypothesis" [color=red];
|
||||
"run_analysis_pipeline" -> "to_dict" [color=red];
|
||||
"DataCleaner" -> "u" [color=gray];
|
||||
"DataCleaner" -> "c" [color=gray];
|
||||
"run_analysis_pipeline" -> "remove_nans" [color=red];
|
||||
"run_analysis_pipeline" -> "remove_outliers" [color=red];
|
||||
"run_analysis_pipeline" -> "full_report" [color=red];
|
||||
"run_analysis_pipeline" -> "normality_test" [color=red];
|
||||
"run_analysis_pipeline" -> "add_descriptive" [color=red];
|
||||
"run_analysis_pipeline" -> "add_hypothesis" [color=red];
|
||||
"run_analysis_pipeline" -> "to_dict" [color=red];
|
||||
"DescriptiveStats" -> "u" [color=gray];
|
||||
"DescriptiveStats" -> "c" [color=gray];
|
||||
"run_analysis_pipeline" -> "remove_nans" [color=red];
|
||||
"run_analysis_pipeline" -> "remove_outliers" [color=red];
|
||||
"run_analysis_pipeline" -> "full_report" [color=red];
|
||||
"run_analysis_pipeline" -> "normality_test" [color=red];
|
||||
"run_analysis_pipeline" -> "add_descriptive" [color=red];
|
||||
"run_analysis_pipeline" -> "add_hypothesis" [color=red];
|
||||
"run_analysis_pipeline" -> "to_dict" [color=red];
|
||||
"DescriptiveStats" -> "u" [color=gray];
|
||||
"DescriptiveStats" -> "c" [color=gray];
|
||||
"run_analysis_pipeline" -> "remove_nans" [color=red];
|
||||
"run_analysis_pipeline" -> "remove_outliers" [color=red];
|
||||
"run_analysis_pipeline" -> "full_report" [color=red];
|
||||
"run_analysis_pipeline" -> "normality_test" [color=red];
|
||||
"run_analysis_pipeline" -> "add_descriptive" [color=red];
|
||||
"run_analysis_pipeline" -> "add_hypothesis" [color=red];
|
||||
"run_analysis_pipeline" -> "to_dict" [color=red];
|
||||
"DescriptiveStats" -> "u" [color=gray];
|
||||
"DescriptiveStats" -> "c" [color=gray];
|
||||
"run_analysis_pipeline" -> "remove_nans" [color=red];
|
||||
"run_analysis_pipeline" -> "remove_outliers" [color=red];
|
||||
"run_analysis_pipeline" -> "full_report" [color=red];
|
||||
"run_analysis_pipeline" -> "normality_test" [color=red];
|
||||
"run_analysis_pipeline" -> "add_descriptive" [color=red];
|
||||
"run_analysis_pipeline" -> "add_hypothesis" [color=red];
|
||||
"run_analysis_pipeline" -> "to_dict" [color=red];
|
||||
"DescriptiveStats" -> "u" [color=gray];
|
||||
"DescriptiveStats" -> "c" [color=gray];
|
||||
"run_analysis_pipeline" -> "remove_nans" [color=red];
|
||||
"run_analysis_pipeline" -> "remove_outliers" [color=red];
|
||||
"run_analysis_pipeline" -> "full_report" [color=red];
|
||||
"run_analysis_pipeline" -> "normality_test" [color=red];
|
||||
"run_analysis_pipeline" -> "add_descriptive" [color=red];
|
||||
"run_analysis_pipeline" -> "add_hypothesis" [color=red];
|
||||
"run_analysis_pipeline" -> "to_dict" [color=red];
|
||||
"DescriptiveStats" -> "u" [color=gray];
|
||||
"DescriptiveStats" -> "c" [color=gray];
|
||||
"run_analysis_pipeline" -> "remove_nans" [color=red];
|
||||
"run_analysis_pipeline" -> "remove_outliers" [color=red];
|
||||
"run_analysis_pipeline" -> "full_report" [color=red];
|
||||
"run_analysis_pipeline" -> "normality_test" [color=red];
|
||||
"run_analysis_pipeline" -> "add_descriptive" [color=red];
|
||||
"run_analysis_pipeline" -> "add_hypothesis" [color=red];
|
||||
"run_analysis_pipeline" -> "to_dict" [color=red];
|
||||
"DescriptiveStats" -> "u" [color=gray];
|
||||
"DescriptiveStats" -> "c" [color=gray];
|
||||
"run_analysis_pipeline" -> "remove_nans" [color=red];
|
||||
"run_analysis_pipeline" -> "remove_outliers" [color=red];
|
||||
"run_analysis_pipeline" -> "full_report" [color=red];
|
||||
"run_analysis_pipeline" -> "normality_test" [color=red];
|
||||
"run_analysis_pipeline" -> "add_descriptive" [color=red];
|
||||
"run_analysis_pipeline" -> "add_hypothesis" [color=red];
|
||||
"run_analysis_pipeline" -> "to_dict" [color=red];
|
||||
"DescriptiveStats" -> "u" [color=gray];
|
||||
"DescriptiveStats" -> "c" [color=gray];
|
||||
"run_analysis_pipeline" -> "remove_nans" [color=red];
|
||||
"run_analysis_pipeline" -> "remove_outliers" [color=red];
|
||||
"run_analysis_pipeline" -> "full_report" [color=red];
|
||||
"run_analysis_pipeline" -> "normality_test" [color=red];
|
||||
"run_analysis_pipeline" -> "add_descriptive" [color=red];
|
||||
"run_analysis_pipeline" -> "add_hypothesis" [color=red];
|
||||
"run_analysis_pipeline" -> "to_dict" [color=red];
|
||||
"DescriptiveStats" -> "u" [color=gray];
|
||||
"DescriptiveStats" -> "c" [color=gray];
|
||||
"DescriptiveStats" -> "full_report" [color=black];
|
||||
"DescriptiveStats" -> "full_report" [color=black];
|
||||
"DescriptiveStats" -> "full_report" [color=black];
|
||||
"DescriptiveStats" -> "full_report" [color=black];
|
||||
"DescriptiveStats" -> "full_report" [color=black];
|
||||
"DescriptiveStats" -> "full_report" [color=black];
|
||||
"DescriptiveStats" -> "full_report" [color=black];
|
||||
"DescriptiveStats" -> "full_report" [color=black];
|
||||
"run_analysis_pipeline" -> "remove_nans" [color=red];
|
||||
"run_analysis_pipeline" -> "remove_outliers" [color=red];
|
||||
"run_analysis_pipeline" -> "full_report" [color=red];
|
||||
"run_analysis_pipeline" -> "normality_test" [color=red];
|
||||
"run_analysis_pipeline" -> "add_descriptive" [color=red];
|
||||
"run_analysis_pipeline" -> "add_hypothesis" [color=red];
|
||||
"run_analysis_pipeline" -> "to_dict" [color=red];
|
||||
"DescriptiveStats" -> "u" [color=gray];
|
||||
"DescriptiveStats" -> "c" [color=gray];
|
||||
"run_analysis_pipeline" -> "remove_nans" [color=red];
|
||||
"run_analysis_pipeline" -> "remove_outliers" [color=red];
|
||||
"run_analysis_pipeline" -> "full_report" [color=red];
|
||||
"run_analysis_pipeline" -> "normality_test" [color=red];
|
||||
"run_analysis_pipeline" -> "add_descriptive" [color=red];
|
||||
"run_analysis_pipeline" -> "add_hypothesis" [color=red];
|
||||
"run_analysis_pipeline" -> "to_dict" [color=red];
|
||||
"HypothesisTester" -> "c" [color=gray];
|
||||
"run_analysis_pipeline" -> "remove_nans" [color=red];
|
||||
"run_analysis_pipeline" -> "remove_outliers" [color=red];
|
||||
"run_analysis_pipeline" -> "full_report" [color=red];
|
||||
"run_analysis_pipeline" -> "normality_test" [color=red];
|
||||
"run_analysis_pipeline" -> "add_descriptive" [color=red];
|
||||
"run_analysis_pipeline" -> "add_hypothesis" [color=red];
|
||||
"run_analysis_pipeline" -> "to_dict" [color=red];
|
||||
"HypothesisTester" -> "c" [color=gray];
|
||||
"run_analysis_pipeline" -> "remove_nans" [color=red];
|
||||
"run_analysis_pipeline" -> "remove_outliers" [color=red];
|
||||
"run_analysis_pipeline" -> "full_report" [color=red];
|
||||
"run_analysis_pipeline" -> "normality_test" [color=red];
|
||||
"run_analysis_pipeline" -> "add_descriptive" [color=red];
|
||||
"run_analysis_pipeline" -> "add_hypothesis" [color=red];
|
||||
"run_analysis_pipeline" -> "to_dict" [color=red];
|
||||
"HypothesisTester" -> "c" [color=gray];
|
||||
"run_analysis_pipeline" -> "remove_nans" [color=red];
|
||||
"run_analysis_pipeline" -> "remove_outliers" [color=red];
|
||||
"run_analysis_pipeline" -> "full_report" [color=red];
|
||||
"run_analysis_pipeline" -> "normality_test" [color=red];
|
||||
"run_analysis_pipeline" -> "add_descriptive" [color=red];
|
||||
"run_analysis_pipeline" -> "add_hypothesis" [color=red];
|
||||
"run_analysis_pipeline" -> "to_dict" [color=red];
|
||||
"HypothesisTester" -> "c" [color=gray];
|
||||
"run_analysis_pipeline" -> "remove_nans" [color=red];
|
||||
"run_analysis_pipeline" -> "remove_outliers" [color=red];
|
||||
"run_analysis_pipeline" -> "full_report" [color=red];
|
||||
"run_analysis_pipeline" -> "normality_test" [color=red];
|
||||
"run_analysis_pipeline" -> "add_descriptive" [color=red];
|
||||
"run_analysis_pipeline" -> "add_hypothesis" [color=red];
|
||||
"run_analysis_pipeline" -> "to_dict" [color=red];
|
||||
"HypothesisTester" -> "c" [color=gray];
|
||||
"run_analysis_pipeline" -> "remove_nans" [color=red];
|
||||
"run_analysis_pipeline" -> "remove_outliers" [color=red];
|
||||
"run_analysis_pipeline" -> "full_report" [color=red];
|
||||
"run_analysis_pipeline" -> "normality_test" [color=red];
|
||||
"run_analysis_pipeline" -> "add_descriptive" [color=red];
|
||||
"run_analysis_pipeline" -> "add_hypothesis" [color=red];
|
||||
"run_analysis_pipeline" -> "to_dict" [color=red];
|
||||
"HypothesisTester" -> "c" [color=gray];
|
||||
"run_analysis_pipeline" -> "remove_nans" [color=red];
|
||||
"run_analysis_pipeline" -> "remove_outliers" [color=red];
|
||||
"run_analysis_pipeline" -> "full_report" [color=red];
|
||||
"run_analysis_pipeline" -> "normality_test" [color=red];
|
||||
"run_analysis_pipeline" -> "add_descriptive" [color=red];
|
||||
"run_analysis_pipeline" -> "add_hypothesis" [color=red];
|
||||
"run_analysis_pipeline" -> "to_dict" [color=red];
|
||||
"CurveFitter" -> "u" [color=gray];
|
||||
"run_analysis_pipeline" -> "remove_nans" [color=red];
|
||||
"run_analysis_pipeline" -> "remove_outliers" [color=red];
|
||||
"run_analysis_pipeline" -> "full_report" [color=red];
|
||||
"run_analysis_pipeline" -> "normality_test" [color=red];
|
||||
"run_analysis_pipeline" -> "add_descriptive" [color=red];
|
||||
"run_analysis_pipeline" -> "add_hypothesis" [color=red];
|
||||
"run_analysis_pipeline" -> "to_dict" [color=red];
|
||||
"CurveFitter" -> "u" [color=gray];
|
||||
"run_analysis_pipeline" -> "remove_nans" [color=red];
|
||||
"run_analysis_pipeline" -> "remove_outliers" [color=red];
|
||||
"run_analysis_pipeline" -> "full_report" [color=red];
|
||||
"run_analysis_pipeline" -> "normality_test" [color=red];
|
||||
"run_analysis_pipeline" -> "add_descriptive" [color=red];
|
||||
"run_analysis_pipeline" -> "add_hypothesis" [color=red];
|
||||
"run_analysis_pipeline" -> "to_dict" [color=red];
|
||||
"CurveFitter" -> "u" [color=gray];
|
||||
"run_analysis_pipeline" -> "remove_nans" [color=red];
|
||||
"run_analysis_pipeline" -> "remove_outliers" [color=red];
|
||||
"run_analysis_pipeline" -> "full_report" [color=red];
|
||||
"run_analysis_pipeline" -> "normality_test" [color=red];
|
||||
"run_analysis_pipeline" -> "add_descriptive" [color=red];
|
||||
"run_analysis_pipeline" -> "add_hypothesis" [color=red];
|
||||
"run_analysis_pipeline" -> "to_dict" [color=red];
|
||||
"CurveFitter" -> "u" [color=gray];
|
||||
"run_analysis_pipeline" -> "remove_nans" [color=red];
|
||||
"run_analysis_pipeline" -> "remove_outliers" [color=red];
|
||||
"run_analysis_pipeline" -> "full_report" [color=red];
|
||||
"run_analysis_pipeline" -> "normality_test" [color=red];
|
||||
"run_analysis_pipeline" -> "add_descriptive" [color=red];
|
||||
"run_analysis_pipeline" -> "add_hypothesis" [color=red];
|
||||
"run_analysis_pipeline" -> "to_dict" [color=red];
|
||||
"CurveFitter" -> "u" [color=gray];
|
||||
"run_analysis_pipeline" -> "remove_nans" [color=red];
|
||||
"run_analysis_pipeline" -> "remove_outliers" [color=red];
|
||||
"run_analysis_pipeline" -> "full_report" [color=red];
|
||||
"run_analysis_pipeline" -> "normality_test" [color=red];
|
||||
"run_analysis_pipeline" -> "add_descriptive" [color=red];
|
||||
"run_analysis_pipeline" -> "add_hypothesis" [color=red];
|
||||
"run_analysis_pipeline" -> "to_dict" [color=red];
|
||||
"CurveFitter" -> "u" [color=gray];
|
||||
"CurveFitter" -> "r_squared" [color=black];
|
||||
"run_analysis_pipeline" -> "remove_nans" [color=red];
|
||||
"run_analysis_pipeline" -> "remove_outliers" [color=red];
|
||||
"run_analysis_pipeline" -> "full_report" [color=red];
|
||||
"run_analysis_pipeline" -> "normality_test" [color=red];
|
||||
"run_analysis_pipeline" -> "add_descriptive" [color=red];
|
||||
"run_analysis_pipeline" -> "add_hypothesis" [color=red];
|
||||
"run_analysis_pipeline" -> "to_dict" [color=red];
|
||||
"CurveFitter" -> "u" [color=gray];
|
||||
"run_analysis_pipeline" -> "remove_nans" [color=red];
|
||||
"run_analysis_pipeline" -> "remove_outliers" [color=red];
|
||||
"run_analysis_pipeline" -> "full_report" [color=red];
|
||||
"run_analysis_pipeline" -> "normality_test" [color=red];
|
||||
"run_analysis_pipeline" -> "add_descriptive" [color=red];
|
||||
"run_analysis_pipeline" -> "add_hypothesis" [color=red];
|
||||
"run_analysis_pipeline" -> "to_dict" [color=red];
|
||||
"ReportGenerator" -> "add_descriptive" [color=blue];
|
||||
"run_analysis_pipeline" -> "remove_nans" [color=red];
|
||||
"run_analysis_pipeline" -> "remove_outliers" [color=red];
|
||||
"run_analysis_pipeline" -> "full_report" [color=red];
|
||||
"run_analysis_pipeline" -> "normality_test" [color=red];
|
||||
"run_analysis_pipeline" -> "add_descriptive" [color=red];
|
||||
"run_analysis_pipeline" -> "add_hypothesis" [color=red];
|
||||
"run_analysis_pipeline" -> "to_dict" [color=red];
|
||||
"ReportGenerator" -> "add_hypothesis" [color=blue];
|
||||
"run_analysis_pipeline" -> "remove_nans" [color=red];
|
||||
"run_analysis_pipeline" -> "remove_outliers" [color=red];
|
||||
"run_analysis_pipeline" -> "full_report" [color=red];
|
||||
"run_analysis_pipeline" -> "normality_test" [color=red];
|
||||
"run_analysis_pipeline" -> "add_descriptive" [color=red];
|
||||
"run_analysis_pipeline" -> "add_hypothesis" [color=red];
|
||||
"run_analysis_pipeline" -> "to_dict" [color=red];
|
||||
"ReportGenerator" -> "add_curve_fit" [color=blue];
|
||||
"run_analysis_pipeline" -> "remove_nans" [color=red];
|
||||
"run_analysis_pipeline" -> "remove_outliers" [color=red];
|
||||
"run_analysis_pipeline" -> "full_report" [color=red];
|
||||
"run_analysis_pipeline" -> "normality_test" [color=red];
|
||||
"run_analysis_pipeline" -> "add_descriptive" [color=red];
|
||||
"run_analysis_pipeline" -> "add_hypothesis" [color=red];
|
||||
"run_analysis_pipeline" -> "to_dict" [color=red];
|
||||
"run_analysis_pipeline" -> "remove_nans" [color=red];
|
||||
"run_analysis_pipeline" -> "remove_outliers" [color=red];
|
||||
"run_analysis_pipeline" -> "full_report" [color=red];
|
||||
"run_analysis_pipeline" -> "normality_test" [color=red];
|
||||
"run_analysis_pipeline" -> "add_descriptive" [color=red];
|
||||
"run_analysis_pipeline" -> "add_hypothesis" [color=red];
|
||||
"run_analysis_pipeline" -> "to_dict" [color=red];
|
||||
"ReportGenerator" -> "save" [color=black];
|
||||
"run_analysis_pipeline" -> "remove_nans" [color=red];
|
||||
"run_analysis_pipeline" -> "remove_outliers" [color=red];
|
||||
"run_analysis_pipeline" -> "full_report" [color=red];
|
||||
"run_analysis_pipeline" -> "normality_test" [color=red];
|
||||
"run_analysis_pipeline" -> "add_descriptive" [color=red];
|
||||
"run_analysis_pipeline" -> "add_hypothesis" [color=red];
|
||||
"run_analysis_pipeline" -> "to_dict" [color=red];
|
||||
}
|
||||
BIN
AST Files/dependency_graph.png
Normal file
BIN
AST Files/dependency_graph.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 252 KiB |
@ -169,7 +169,20 @@ print("=" * 60)
|
||||
def get_param_types(func_node: ast.FunctionDef) -> dict[str, str]:
|
||||
"""Map parameter name -> annotation type name."""
|
||||
# TODO: implement
|
||||
return {}
|
||||
param_types = {}
|
||||
|
||||
for arg in func_node.args.args:
|
||||
if arg.arg == "self":
|
||||
continue
|
||||
|
||||
name = arg.arg
|
||||
|
||||
if isinstance(arg.annotation, ast.Name):
|
||||
param_types[name] = arg.annotation.id
|
||||
elif isinstance(arg.annotation, ast.Attribute):
|
||||
param_types[name] = ast.unparse(arg.annotation)
|
||||
|
||||
return param_types
|
||||
|
||||
|
||||
# TODO 6: Write a function `find_cross_class_calls(cls_name, method_name)`
|
||||
@ -184,16 +197,29 @@ def get_param_types(func_node: ast.FunctionDef) -> dict[str, str]:
|
||||
def find_cross_class_calls(cls_name: str, method_name: str) -> list[tuple[str, str]]:
|
||||
"""Return [(target_class, target_method), ...] for cross-class calls."""
|
||||
# TODO: implement
|
||||
return []
|
||||
class_methods = class_info[cls_name]["methods"]
|
||||
method = class_methods[method_name]
|
||||
|
||||
param_types = get_param_types(method)
|
||||
calls = extract_calls(method)
|
||||
|
||||
cross_class_calls = []
|
||||
|
||||
for name, param_type in param_types.items():
|
||||
for call in calls:
|
||||
if name == call.get("object"):
|
||||
cross_class_calls.append((param_type, call["method"]))
|
||||
|
||||
return cross_class_calls
|
||||
|
||||
|
||||
# TODO 7: Print cross-class call edges.
|
||||
|
||||
# for cls_name, info in class_info.items():
|
||||
# for method_name in info["methods"]:
|
||||
# cross = find_cross_class_calls(cls_name, method_name)
|
||||
# for target_cls, target_method in cross:
|
||||
# print(f" {cls_name}.{method_name}() -> {target_cls}.{target_method}()")
|
||||
for cls_name, info in class_info.items():
|
||||
for method_name in info["methods"]:
|
||||
cross = find_cross_class_calls(cls_name, method_name)
|
||||
for target_cls, target_method in cross:
|
||||
print(f" {cls_name}.{method_name}() -> {target_cls}.{target_method}()")
|
||||
|
||||
|
||||
# ── Part D: Full Call Graph as Adjacency List ──────────────────────────────
|
||||
@ -209,22 +235,22 @@ print("=" * 60)
|
||||
# Also analyse run_analysis_pipeline() which instantiates classes
|
||||
# and calls their methods.
|
||||
|
||||
# call_graph = defaultdict(list)
|
||||
#
|
||||
# # Add internal calls
|
||||
# for cls_name, info in class_info.items():
|
||||
# for method_name in info["methods"]:
|
||||
# source = f"{cls_name}.{method_name}"
|
||||
# for target in find_internal_calls(cls_name, method_name):
|
||||
# call_graph[source].append(f"{cls_name}.{target}")
|
||||
# for target_cls, target_method in find_cross_class_calls(cls_name, method_name):
|
||||
# call_graph[source].append(f"{target_cls}.{target_method}")
|
||||
#
|
||||
# # Print the graph
|
||||
# for source, targets in sorted(call_graph.items()):
|
||||
# print(f" {source}")
|
||||
# for t in targets:
|
||||
# print(f" -> {t}")
|
||||
call_graph = defaultdict(list)
|
||||
|
||||
# Add internal calls
|
||||
for cls_name, info in class_info.items():
|
||||
for method_name in info["methods"]:
|
||||
source = f"{cls_name}.{method_name}"
|
||||
for target in find_internal_calls(cls_name, method_name):
|
||||
call_graph[source].append(f"{cls_name}.{target} (internal)")
|
||||
for target_cls, target_method in find_cross_class_calls(cls_name, method_name):
|
||||
call_graph[source].append(f"{target_cls}.{target_method} (cross-class)")
|
||||
|
||||
# Print the graph
|
||||
for source, targets in sorted(call_graph.items()):
|
||||
print(f" {source}")
|
||||
for t in targets:
|
||||
print(f" -> {t}")
|
||||
|
||||
|
||||
# ── Expected Output (key edges) ────────────────────────────────────────────
|
||||
|
||||
@ -88,15 +88,15 @@ print("=" * 60)
|
||||
alias_to_module: dict[str, str] = {}
|
||||
|
||||
# TODO: iterate over tree.body and fill alias_to_module
|
||||
# for node in tree.body:
|
||||
# if isinstance(node, ast.Import):
|
||||
# for alias in node.names:
|
||||
# key = alias.asname if alias.asname else alias.name
|
||||
# alias_to_module[key] = alias.name
|
||||
# elif isinstance(node, ast.ImportFrom):
|
||||
# for alias in node.names:
|
||||
# key = alias.asname if alias.asname else alias.name
|
||||
# alias_to_module[key] = node.module or ""
|
||||
for node in tree.body:
|
||||
if isinstance(node, ast.Import):
|
||||
for alias in node.names:
|
||||
key = alias.asname if alias.asname else alias.name
|
||||
alias_to_module[key] = alias.name
|
||||
elif isinstance(node, ast.ImportFrom):
|
||||
for alias in node.names:
|
||||
key = alias.asname if alias.asname else alias.name
|
||||
alias_to_module[key] = node.module or ""
|
||||
|
||||
|
||||
# TODO 2: For each class, find which external modules its methods call.
|
||||
@ -112,12 +112,27 @@ def get_external_deps(cls_name: str) -> set[str]:
|
||||
"""Return the set of external module names used by *cls_name*."""
|
||||
deps = set()
|
||||
# TODO: implement
|
||||
|
||||
methods = class_info[cls_name]["methods"]
|
||||
|
||||
for method in methods.values():
|
||||
func_calls = extract_calls(method)
|
||||
|
||||
for call in func_calls:
|
||||
obj = call.get("object")
|
||||
if not obj:
|
||||
continue
|
||||
|
||||
dep = alias_to_module.get(str(obj))
|
||||
if dep:
|
||||
deps.add(dep)
|
||||
|
||||
return deps
|
||||
|
||||
|
||||
# for cls_name in class_info:
|
||||
# deps = get_external_deps(cls_name)
|
||||
# print(f"\n {cls_name}: {sorted(deps) if deps else '(none)'}")
|
||||
for cls_name in class_info:
|
||||
deps = get_external_deps(cls_name)
|
||||
print(f"\n {cls_name}: {sorted(deps) if deps else '(none)'}")
|
||||
|
||||
|
||||
# ── Part B: Analyse run_analysis_pipeline for Data Flow ────────────────────
|
||||
@ -135,6 +150,9 @@ print("=" * 60)
|
||||
|
||||
pipeline_func = None
|
||||
# TODO: find it in tree.body
|
||||
for node in ast.walk(tree):
|
||||
if isinstance(node, ast.FunctionDef) and node.name == "run_analysis_pipeline":
|
||||
pipeline_func = node
|
||||
|
||||
# TODO 4: Walk the pipeline function and find all variable assignments.
|
||||
# For each ast.Assign where the right-hand side is a Call:
|
||||
@ -149,7 +167,14 @@ pipeline_func = None
|
||||
var_types: dict[str, str] = {}
|
||||
|
||||
# TODO: implement by walking pipeline_func
|
||||
if pipeline_func:
|
||||
for node in pipeline_func.body:
|
||||
if isinstance(node, ast.Assign) and isinstance(node.value, ast.Call):
|
||||
for target in node.targets:
|
||||
var_types[ast.unparse(target)] = ast.unparse(node.value.func)
|
||||
|
||||
for target, value in var_types.items():
|
||||
print(f"\n {target}: {value}")
|
||||
|
||||
# TODO 5: Now trace method calls on those variables.
|
||||
# For each attribute call (e.g. cleaner.remove_nans()):
|
||||
@ -162,9 +187,19 @@ pipeline_edges: list[tuple[str, str]] = []
|
||||
|
||||
# TODO: implement
|
||||
|
||||
# print("\n Data flow edges:")
|
||||
# for source, target in pipeline_edges:
|
||||
# print(f" {source} -> {target}")
|
||||
if pipeline_func:
|
||||
calls = extract_calls(pipeline_func)
|
||||
|
||||
for call in calls:
|
||||
if call["type"] == "attribute" and call["object"] in var_types.keys():
|
||||
type_name = var_types[call["object"]]
|
||||
# pipeline_edges.append(("run_analysis_pipeline", f"{type_name}.{call["method"]}"))
|
||||
pipeline_edges.append(("run_analysis_pipeline", f"{call["method"]}"))
|
||||
|
||||
|
||||
print("\n Data flow edges:")
|
||||
for source, target in pipeline_edges:
|
||||
print(f" {source} -> {target}")
|
||||
|
||||
|
||||
# ── Part C: Export to DOT Format ────────────────────────────────────────────
|
||||
@ -183,10 +218,21 @@ print("=" * 60)
|
||||
# Use the format: (source_label, target_label, edge_type)
|
||||
# where edge_type is one of: "internal", "cross_class", "pipeline", "external"
|
||||
|
||||
from ex03_method_call_graph import find_internal_calls, find_cross_class_calls
|
||||
|
||||
all_edges: list[tuple[str, str, str]] = []
|
||||
|
||||
# TODO: collect all edges
|
||||
|
||||
for cls_name, cls_info in class_info.items():
|
||||
for method_name in cls_info["methods"].keys():
|
||||
for internal in find_internal_calls(cls_name, method_name):
|
||||
all_edges.append((cls_name, method_name, "internal"))
|
||||
for cross_class in find_cross_class_calls(cls_name, method_name):
|
||||
all_edges.append((cls_name, method_name, "cross_class"))
|
||||
for pipeline_edge in pipeline_edges:
|
||||
all_edges.append((pipeline_edge[0], pipeline_edge[1], "pipeline"))
|
||||
for external_dep in get_external_deps(cls_name):
|
||||
all_edges.append((cls_name, external_dep[1], "external"))
|
||||
|
||||
# TODO 7: Generate a DOT string and write it to "dependency_graph.dot".
|
||||
#
|
||||
@ -207,14 +253,32 @@ all_edges: list[tuple[str, str, str]] = []
|
||||
def generate_dot(edges: list[tuple[str, str, str]]) -> str:
|
||||
"""Return a DOT-format string for the dependency graph."""
|
||||
# TODO: implement
|
||||
return "digraph G {\n}\n"
|
||||
EDGE_COLORS = {
|
||||
"internal": "black",
|
||||
"cross_class": "blue",
|
||||
"pipeline": "red",
|
||||
"external": "gray",
|
||||
}
|
||||
|
||||
lines = [
|
||||
"digraph G {",
|
||||
" rankdir=LR;",
|
||||
' node [shape=box, style=filled, fillcolor=lightblue];',
|
||||
]
|
||||
|
||||
for source, target, edge_type in edges:
|
||||
color = EDGE_COLORS.get(edge_type, "black")
|
||||
lines.append(f' "{source}" -> "{target}" [color={color}];')
|
||||
|
||||
lines.append("}")
|
||||
return "\n".join(lines) + "\n"
|
||||
|
||||
|
||||
# dot_string = generate_dot(all_edges)
|
||||
# dot_file = Path(__file__).parent / "dependency_graph.dot"
|
||||
# dot_file.write_text(dot_string)
|
||||
# print(f"\n Written to {dot_file}")
|
||||
# print(f" Render with: dot -Tpng dependency_graph.dot -o dependency_graph.png")
|
||||
dot_string = generate_dot(all_edges)
|
||||
dot_file = Path(__file__).parent / "dependency_graph.dot"
|
||||
dot_file.write_text(dot_string)
|
||||
print(f"\n Written to {dot_file}")
|
||||
print(f" Render with: dot -Tpng dependency_graph.dot -o dependency_graph.png")
|
||||
|
||||
|
||||
# ── Part D: (Optional) Render with networkx + matplotlib ───────────────────
|
||||
@ -228,51 +292,50 @@ print("=" * 60)
|
||||
#
|
||||
# TODO 9: Build a networkx DiGraph from all_edges and render it.
|
||||
#
|
||||
# import networkx as nx
|
||||
# import matplotlib.pyplot as plt
|
||||
#
|
||||
# G = nx.DiGraph()
|
||||
#
|
||||
# # Color map for edge types
|
||||
# edge_colors = {
|
||||
# "internal": "black",
|
||||
# "cross_class": "blue",
|
||||
# "pipeline": "red",
|
||||
# "external": "gray",
|
||||
# }
|
||||
#
|
||||
# # Add edges with colors
|
||||
# for source, target, etype in all_edges:
|
||||
# G.add_edge(source, target, color=edge_colors.get(etype, "black"))
|
||||
#
|
||||
# # Node colors: classes in light blue, functions in light green, modules in light gray
|
||||
# node_colors = []
|
||||
# for n in G.nodes():
|
||||
# if "." in n and n.split(".")[0] in class_info:
|
||||
# node_colors.append("lightblue")
|
||||
# elif n in module_functions:
|
||||
# node_colors.append("lightgreen")
|
||||
# else:
|
||||
# node_colors.append("lightgray")
|
||||
#
|
||||
# # Draw
|
||||
# pos = nx.spring_layout(G, k=2, seed=42)
|
||||
# colors = [G[u][v]["color"] for u, v in G.edges()]
|
||||
#
|
||||
# plt.figure(figsize=(16, 10))
|
||||
# nx.draw(G, pos,
|
||||
# with_labels=True,
|
||||
# node_color=node_colors,
|
||||
# edge_color=colors,
|
||||
# node_size=2000,
|
||||
# font_size=7,
|
||||
# arrows=True,
|
||||
# arrowsize=15)
|
||||
# plt.title("Dependency Graph – sample_stats.py")
|
||||
# plt.tight_layout()
|
||||
# plt.savefig(Path(__file__).parent / "dependency_graph.png", dpi=150)
|
||||
# plt.show()
|
||||
# print(" Saved dependency_graph.png")
|
||||
import networkx as nx
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
G = nx.DiGraph()
|
||||
|
||||
# Color map for edge types
|
||||
edge_colors = {
|
||||
"internal": "black",
|
||||
"cross_class": "blue",
|
||||
"pipeline": "red",
|
||||
"external": "gray",
|
||||
}
|
||||
|
||||
# Add edges with colors
|
||||
for source, target, etype in all_edges:
|
||||
G.add_edge(source, target, color=edge_colors.get(etype, "black"))
|
||||
|
||||
# Node colors: classes in light blue, functions in light green, modules in light gray
|
||||
node_colors = []
|
||||
for n in G.nodes():
|
||||
if "." in n and n.split(".")[0] in class_info:
|
||||
node_colors.append("lightblue")
|
||||
elif n in module_functions:
|
||||
node_colors.append("lightgreen")
|
||||
else:
|
||||
node_colors.append("lightgray")
|
||||
|
||||
# Draw
|
||||
pos = nx.spring_layout(G, k=2, seed=42)
|
||||
colors = [G[u][v]["color"] for u, v in G.edges()]
|
||||
|
||||
plt.figure(figsize=(16, 10))
|
||||
nx.draw(G, pos,
|
||||
with_labels=True,
|
||||
node_color=node_colors,
|
||||
edge_color=colors,
|
||||
node_size=2000,
|
||||
font_size=7,
|
||||
arrowsize=15)
|
||||
plt.title("Dependency Graph – sample_stats.py")
|
||||
plt.tight_layout()
|
||||
plt.savefig(Path(__file__).parent / "dependency_graph.png", dpi=150)
|
||||
plt.show()
|
||||
print(" Saved dependency_graph.png")
|
||||
|
||||
print("\n (Uncomment the code above after installing networkx and matplotlib)")
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user