Skip to content

Commit cfe5f6c

Browse files
authored
Merge pull request #8 from shresthalucky/master
Refactor following PEP conventions
2 parents 0b6ad8d + 9dcdea3 commit cfe5f6c

File tree

1 file changed

+104
-69
lines changed

1 file changed

+104
-69
lines changed

visualiser/visualiser.py

Lines changed: 104 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
dot_str_body = ""
1414
dot_str_end = "}"
1515

16+
1617
class Visualiser(object):
1718
# Total number of nodes
1819
node_count = 0
@@ -22,8 +23,9 @@ class Visualiser(object):
2223
edges = []
2324
nodes = []
2425

25-
def __init__(self, ignore_args=None, show_argument_name=True, show_return_value=True, node_properties_kwargs={}):
26-
#If enabled shows keyword arguments ordered by keys
26+
def __init__(self, ignore_args=None, show_argument_name=True,
27+
show_return_value=True, node_properties_kwargs={}):
28+
# If enabled shows keyword arguments ordered by keys
2729
self.show_argument_name = show_argument_name
2830
# If enables shows the return value at every nodes
2931
self.show_return_value = show_return_value
@@ -36,8 +38,6 @@ def __init__(self, ignore_args=None, show_argument_name=True, show_return_value=
3638
else:
3739
self.ignore_args = ['node_num'] + ignore_args
3840

39-
40-
4141
@classmethod
4242
def write_image(cls, filename="out.png"):
4343
try:
@@ -78,8 +78,15 @@ def make_frames(cls):
7878
@classmethod
7979
def write_gif(cls, name="out.gif", delay=3):
8080
images = []
81-
imgs = glob.glob("frames/*.png")
82-
for filename in sorted(imgs, key=lambda fn: int(fn.split("_")[1].split(".")[0])):
81+
82+
# sort frames images in ascending order to number in image filename
83+
# image filename: frames/temp_1.png
84+
sorted_images = sorted(
85+
glob.glob("frames/*.png"),
86+
key=lambda fn: int(fn.split("_")[1].split(".")[0])
87+
)
88+
89+
for filename in sorted_images:
8390
images.append(imageio.imread(filename))
8491
print("Writing gif...")
8592
imageio.mimsave(name, images, duration=delay)
@@ -107,114 +114,138 @@ def make_animation(cls, filename="out.gif", delay=3):
107114
except:
108115
print("Error saving gif.")
109116

110-
111-
def extract_signature_label_arg_string(self, *args, **kwargs):
117+
def extract_arg_strings(self, *args, **kwargs):
112118
"""
113-
Returns function signature arguments as string and function label arguments as string.
114-
label_argument string contains only the arguments that are not in ignore_args
115-
signature_argument_string contains all the arguments available for the function
119+
Returns function signature arguments function label arguments as
120+
string.
121+
label_args_string contains only the arguments that are not in
122+
ignore_args.
123+
signature_args_string contains all the arguments available for the
124+
function.
116125
"""
117-
# If show_argument flag is True(default)
118-
# Then argument_string is:
119-
# a=1, b=31, c=0
120-
signature_argument_string = ', '.join([repr(a) for a in args] +
121-
[f"{key}={repr(value)}" for key, value in kwargs.items()])
122-
123-
label_argument_string = ', '.join([repr(a) for a in args] +
124-
[f"{key}={repr(value)}"
125-
for key, value in kwargs.items()
126-
if key not in self.ignore_args])
127-
128-
# If show_argument flag is False
129-
# Then argument_string is:
130-
# 1, 31, 0
131-
if not self.show_argument_name:
132-
signature_argument_string = ', '.join([repr(value) for value in args] +
133-
[f"{repr(value)}" for key, value in kwargs.items()])
134-
135-
label_argument_string = ', '.join([repr(a) for a in args] +
136-
[f"{repr(value)}"
137-
for key, value in kwargs.items()
138-
if key not in self.ignore_args])
139-
140-
return signature_argument_string, label_argument_string
126+
127+
def get_kwargs_strings(ignore_args=[]):
128+
"""Returns list of kwargs in string format from given kwargs items
129+
130+
Args:
131+
ignore_args (list, optional) : list of ignored arguments.
132+
Default to [].
133+
134+
Returns:
135+
strings_list: list of kwargs in string format
136+
"""
137+
138+
strings_list = []
139+
140+
for key, value in kwargs.items():
141+
if key not in ignore_args:
142+
if not self.show_argument_name:
143+
strings_list.append(f"{repr(value)}")
144+
else:
145+
strings_list.append(f"{key}={repr(value)}")
146+
147+
return strings_list
148+
149+
args_string = [repr(a) for a in args]
150+
signature_kwargs_string = get_kwargs_strings()
151+
label_kwargs_string = get_kwargs_strings(ignore_args=self.ignore_args)
152+
153+
signature_args_string = ', '.join(
154+
args_string + signature_kwargs_string)
155+
label_args_string = ', '.join(args_string + label_kwargs_string)
156+
157+
return signature_args_string, label_args_string
141158

142159
def __call__(self, fn):
143-
@wraps(fn)
160+
@ wraps(fn)
144161
def wrapper(*args, **kwargs):
145162
global dot_str_body
146163
# Increment total number of nodes when a call is made
147164
self.node_count += 1
148165

149-
# Update kwargs by adding dummy keyword node_num which helps to uniquely identify each node
166+
# Update kwargs by adding dummy keyword node_num which helps to
167+
# uniquely identify each node
150168
kwargs.update({'node_num': self.node_count})
151169
# Order all the keyword arguments
152170
kwargs = OrderedDict(sorted(kwargs.items()))
153171

154-
155172
"""Details about current Function"""
156173
# Get signature and label arguments strings for current function
157-
current_function_argument_string, current_function_label_argument_string = self.extract_signature_label_arg_string(*args, **kwargs)
174+
(signature_args_string,
175+
label_args_string) = self.extract_arg_strings(
176+
*args, **kwargs)
158177

159178
# Details about current function
160-
current_function_name = fn.__name__
179+
function_name = fn.__name__
161180

162181
# Current function signature looks as follows:
163182
# foo(1, 31, 0) or foo(a=1, b=31, c=0)
164-
current_function_signature = f"{current_function_name}(" \
165-
f"{current_function_argument_string})"
166-
current_function_label = f"{current_function_name}({current_function_label_argument_string})"
183+
function_signature = f"{function_name}({signature_args_string})"
184+
function_label = f"{function_name}({label_args_string})"
167185
""""""
168186

169187
"""Details about caller function"""
170-
caller_function_frame = sys._getframe(1)
188+
caller_func_frame = sys._getframe(1)
171189
# All the argument names in caller/parent function
172-
caller_function_argument_names = caller_function_frame.f_code.co_varnames[
173-
:fn.__code__.co_argcount]
174-
caller_function_locals = caller_function_frame.f_locals
190+
caller_func_arg_names = caller_func_frame.f_code.co_varnames[
191+
: fn.__code__.co_argcount]
192+
caller_func_locals = caller_func_frame.f_locals
175193
# Sort all the locals of caller function
176-
caller_function_locals = OrderedDict(sorted(caller_function_locals.items()))
194+
caller_func_locals = OrderedDict(
195+
sorted(caller_func_locals.items()))
196+
197+
caller_func_kwargs = dict()
198+
177199
# Extract only those locals that are in arguments
178-
caller_function_kwargs = {key: value for key, value in caller_function_locals.items() if key in caller_function_argument_names}
200+
for key, value in caller_func_locals.items():
201+
if key in caller_func_arg_names:
202+
caller_func_kwargs[key] = value
179203

180204
# If the nodes has parent node get node_num from parent node
181205
if self.stack:
182-
caller_function_kwargs.update({'node_num': self.stack[-1]})
183-
caller_function_kwargs = OrderedDict(sorted(caller_function_kwargs.items()))
206+
caller_func_kwargs.update({'node_num': self.stack[-1]})
207+
208+
caller_func_kwargs = OrderedDict(
209+
sorted(caller_func_kwargs.items()))
184210

185-
caller_function_argument_string, caller_function_label_argument_string = self.extract_signature_label_arg_string(**caller_function_kwargs)
211+
(caller_func_args_string,
212+
caller_func_label_args_string) = self.extract_arg_strings(
213+
**caller_func_kwargs)
186214

187215
# Caller Function
188-
caller_function_name = caller_function_frame.f_code.co_name
216+
caller_func_name = caller_func_frame.f_code.co_name
189217

190218
# Extract the names of arguments only
191-
caller_func_signature = f"{caller_function_name}({caller_function_argument_string})"
192-
caller_func_label = f"{caller_function_name}({caller_function_label_argument_string})"
219+
caller_func_signature = "{}({})".format(
220+
caller_func_name, caller_func_args_string)
221+
caller_func_label = "{}({})".format(
222+
caller_func_name, caller_func_label_args_string)
193223
""""""
194224

195-
if caller_function_name == '<module>':
196-
print(f"Drawing for {current_function_signature}")
225+
if caller_func_name == '<module>':
226+
print(f"Drawing for {function_signature}")
197227

198228
# Push node_count to stack
199229
self.stack.append(self.node_count)
200230
# Before actual function call delete keyword 'node_num' from kwargs
201231
del kwargs['node_num']
202232

203-
self.edges.append(f'"{caller_func_signature}" -> "{current_function_signature}"')
233+
self.edges.append(
234+
f'"{caller_func_signature}" -> "{function_signature}"')
204235

205236
# Construct node string to be rendered in graphviz
206-
node_string = f'"{current_function_signature}" [label="{current_function_label}"'
237+
node_string = f'"{function_signature}" [label="{function_label}"'
207238

208239
if self.node_properties_kwargs:
209-
node_string += ", " + ", ".join([f'{key}="{value}"' for key, value in self.node_properties_kwargs.items()])
240+
node_string += ", " + \
241+
", ".join([f'{key}="{value}"' for key,
242+
value in self.node_properties_kwargs.items()])
210243

211-
# current_function_label = current_function_label + ", ".join([f"{key}={value}" for key, value in self.node_properties_kwargs.items()])
212244
self.nodes.append(node_string)
213245

214246
# Return after function call
215247
result = fn(*args, **kwargs)
216248

217-
218249
# Pop from tha stack after returning
219250
self.stack.pop()
220251

@@ -223,20 +254,24 @@ def wrapper(*args, **kwargs):
223254
# If shape is set to record
224255
# Then separate function label and return value by a row
225256
if "record" in self.node_properties_kwargs.values():
226-
current_function_label = "{" + current_function_label + f"|{result} }}"
257+
function_label = "{" + \
258+
function_label + f"|{result} }}"
227259
else:
228-
current_function_label += f"\n => {result}"
260+
function_label += f"\n => {result}"
229261

230-
child_node = pydot.Node(name=current_function_signature, label=current_function_label, **self.node_properties_kwargs)
262+
child_node = pydot.Node(name=function_signature,
263+
label=function_label,
264+
**self.node_properties_kwargs)
231265
self.graph.add_node(child_node)
232266

233267
# If the function is called by another function
234-
if caller_function_name not in ['<module>', 'main']:
235-
parent_node = pydot.Node(name=caller_func_signature, label=caller_func_label, **self.node_properties_kwargs)
268+
if caller_func_name not in ['<module>', 'main']:
269+
parent_node = pydot.Node(name=caller_func_signature,
270+
label=caller_func_label,
271+
**self.node_properties_kwargs)
236272
self.graph.add_node(parent_node)
237273
edge = pydot.Edge(parent_node, child_node)
238274
self.graph.add_edge(edge)
239275

240-
241276
return result
242-
return wrapper
277+
return wrapper

0 commit comments

Comments
 (0)