Skip to content

Commit 6031e09

Browse files
author
sarangbishal
committed
Some Code Cleanup
1 parent 707777b commit 6031e09

File tree

3 files changed

+74
-63
lines changed

3 files changed

+74
-63
lines changed

examples/fibonacci.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@ def fib(n, node_num):
1616
right = fib(n=n - 2, node_num=vs.node_count)
1717
return left + right
1818

19-
# Call function
20-
print(fib(n=6, node_num=0))
19+
if __name__ == "__main__":
20+
# Call function
21+
print(fib(n=6, node_num=0))
2122

22-
# Save recursion tree to a file
23-
vs.write_image("fibonacci.png")
23+
# Save recursion tree to a file
24+
vs.write_image("fibonacci.png")

visualiser/fibonacci.png

85.1 KB
Loading

visualiser/visualiser.py

Lines changed: 69 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# Author: Bishal Sarang
2+
13
import sys
24
from functools import wraps
35
from collections import OrderedDict
@@ -14,96 +16,104 @@ def __init__(self, ignore_args, show_argument_name=True, show_return_value=True)
1416
self.ignore_args = ignore_args
1517

1618
@classmethod
17-
def write_image(self, filename="out.png"):
18-
self.graph.write_png(f"{filename}")
19+
def write_image(cls, filename="out.png"):
20+
try:
21+
cls.graph.write_png(f"{filename}")
22+
print(f"File {filename} successfully written")
23+
except Exception:
24+
print(f"Writing {filename} failed")
25+
26+
def extract_signature_label_arg_string(self, *args, **kwargs):
27+
"""
28+
Returns function signature arguments as string and function label arguments as string.
29+
label_argument string contains only the arguments that are not in ignore_args
30+
signature_argument_string contains all the arguments available for the function
31+
"""
32+
# If show_argument flag is True(default)
33+
# Then argument_string is:
34+
# a=1, b=31, c=0
35+
signature_argument_string = ', '.join([repr(a) for a in args] +
36+
[f"{key}={repr(value)}" for key, value in kwargs.items()])
37+
38+
label_argument_string = ', '.join([repr(a) for a in args] +
39+
[f"{key}={repr(value)}"
40+
for key, value in kwargs.items()
41+
if key not in self.ignore_args])
42+
43+
# If show_argument flag is False
44+
# Then argument_string is:
45+
# 1, 31, 0
46+
if not self.show_argument_name:
47+
signature_argument_string = ', '.join([repr(value) for value in args] +
48+
[f"{repr(value)}" for key, value in kwargs.items()])
49+
50+
label_argument_string = ', '.join([repr(a) for a in args] +
51+
[f"{repr(value)}"
52+
for key, value in kwargs.items()
53+
if key not in self.ignore_args])
54+
55+
return signature_argument_string, label_argument_string
1956

2057
def __call__(self, fn):
2158
@wraps(fn)
2259
def wrapper(*args, **kwargs):
2360
# Order all the keyword arguments
2461
kwargs = OrderedDict(sorted(kwargs.items()))
2562

26-
# If show_argument flag is True(default)
27-
# Then argument_string is:
28-
# a=1, b=31, c=0
29-
argument_string = ', '.join(
30-
[repr(a) for a in args] +
31-
[f"{key}={repr(value)}" for key, value in kwargs.items()])
32-
33-
current_function_label_argument_string = ', '.join(
34-
[repr(a) for a in args] +
35-
[f"{key}={repr(value)}" for key, value in kwargs.items() if key not in self.ignore_args])
36-
37-
# If show_argument flag is False
38-
# Then argument_string is:
39-
# 1, 31, 0
40-
if self.show_argument_name == False:
41-
argument_string = ', '.join(
42-
[repr(value) for value in args] +
43-
[f"{repr(value)}" for key, value in kwargs.items()])
44-
45-
current_function_label_argument_string = ', '.join(
46-
[repr(a) for a in args] +
47-
[f"{repr(value)}" for key, value in kwargs.items() if key not in self.ignore_args])
63+
"""Details about current Function"""
64+
# Get signature and label arguments strings for current function
65+
current_function_argument_string, current_function_label_argument_string = self.extract_signature_label_arg_string(*args, **kwargs)
4866

4967
# Details about current function
5068
current_function_name = fn.__name__
51-
current_function_argument_string = argument_string
69+
5270
# Current function signature looks as follows:
5371
# foo(1, 31, 0) or foo(a=1, b=31, c=0)
54-
current_function_signature = f"{current_function_name}({current_function_argument_string})"
72+
current_function_signature = f"{current_function_name}(" \
73+
f"{current_function_argument_string})"
5574
current_function_label = f"{current_function_name}({current_function_label_argument_string})"
56-
57-
# Caller Function
58-
caller_function_name = sys._getframe(1).f_code.co_name
59-
# Extract the names of arguments only
60-
caller_function_argument_names = sys._getframe(1).f_code.co_varnames[:fn.__code__.co_argcount]
61-
caller_function_locals = sys._getframe(1).f_locals
62-
75+
""""""
76+
77+
"""Details about caller function"""
78+
caller_function_frame = sys._getframe(1)
79+
# All the argument names in caller/parent function
80+
caller_function_argument_names = caller_function_frame.f_code.co_varnames[
81+
:fn.__code__.co_argcount]
82+
caller_function_locals = caller_function_frame.f_locals
6383
# Sort all the locals of caller function
6484
caller_function_locals = OrderedDict(sorted(caller_function_locals.items()))
85+
# Extract only those locals that are in arguments
86+
caller_function_kwargs = {key: value for key, value in caller_function_locals.items() if key in caller_function_argument_names}
6587

88+
caller_function_argument_string, caller_function_label_argument_string = self.extract_signature_label_arg_string(**caller_function_kwargs)
6689

67-
# Extract only those locals which are in function signature
68-
caller_function_argument_string = ', '.join(
69-
[f"{key}={value}" for key, value in caller_function_locals.items() if (key in caller_function_argument_names)])
70-
caller_function_label_argument_string = ', '.join(
71-
[f"{key}={value}" for key, value in caller_function_locals.items() if
72-
(key in caller_function_argument_names and key not in self.ignore_args)])
73-
74-
if self.show_argument_name == False:
75-
caller_function_argument_string = ', '.join(
76-
[f"{value}" for key, value in caller_function_locals.items() if
77-
(key in caller_function_argument_names)])
78-
caller_function_label_argument_string = ', '.join(
79-
[f"{value}" for key, value in caller_function_locals.items() if
80-
(key in caller_function_argument_names and key not in self.ignore_args)])
90+
# Caller Function
91+
caller_function_name = caller_function_frame.f_code.co_name
8192

93+
# Extract the names of arguments only
8294
caller_func_signature = f"{caller_function_name}({caller_function_argument_string})"
8395
caller_func_label = f"{caller_function_name}({caller_function_label_argument_string})"
96+
""""""
8497

8598
if caller_function_name == '<module>':
8699
print(f"Drawing for {current_function_signature}")
87100

88101
result = fn(*args, **kwargs)
89102

90-
# #Child Node
91-
child_label = current_function_label
103+
# If show_return_value flag is set, display the result
92104
if self.show_return_value:
93-
child_label += f" => {result}"
94-
child_name = current_function_signature
95-
v = pydot.Node(name=child_name, label=child_label)
96-
self.graph.add_node(v)
105+
current_function_label += f" => {result}"
97106

98-
# Parent Node
99-
u = None
107+
child_node = pydot.Node(name=current_function_signature, label=current_function_label)
108+
self.graph.add_node(child_node)
100109

110+
# If the function is called by another function
101111
if caller_function_name != '<module>':
102112
print(f"Called {current_function_label} by {caller_func_label}")
103-
u = pydot.Node(name=caller_func_signature, label=caller_func_label)
104-
self.graph.add_node(u)
105-
edge = pydot.Edge(u, v)
106-
self.graph.add_edge(edge)
107113

114+
parent_node = pydot.Node(name=caller_func_signature, label=caller_func_label)
115+
self.graph.add_node(parent_node)
116+
edge = pydot.Edge(parent_node, child_node)
117+
self.graph.add_edge(edge)
108118
return result
109119
return wrapper

0 commit comments

Comments
 (0)