ZahirJS commited on
Commit
3c12af9
·
verified ·
1 Parent(s): 7cd1bcd

Create binary_tree_generator.py

Browse files
Files changed (1) hide show
  1. binary_tree_generator.py +141 -0
binary_tree_generator.py ADDED
@@ -0,0 +1,141 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import graphviz
2
+ import json
3
+ from tempfile import NamedTemporaryFile
4
+ import os
5
+
6
+ def generate_binary_tree_diagram(json_input: str, output_format: str) -> str:
7
+ """
8
+ Generates a binary tree diagram from JSON input.
9
+
10
+ Args:
11
+ json_input (str): A JSON string describing the binary tree structure.
12
+ It must follow the Expected JSON Format Example below.
13
+
14
+ Expected JSON Format Example:
15
+ {
16
+ "root": {
17
+ "id": "root",
18
+ "label": "50",
19
+ "left": {
20
+ "id": "left_1",
21
+ "label": "30",
22
+ "left": {
23
+ "id": "left_2",
24
+ "label": "20"
25
+ },
26
+ "right": {
27
+ "id": "right_2",
28
+ "label": "40"
29
+ }
30
+ },
31
+ "right": {
32
+ "id": "right_1",
33
+ "label": "70",
34
+ "left": {
35
+ "id": "left_3",
36
+ "label": "60"
37
+ },
38
+ "right": {
39
+ "id": "right_3",
40
+ "label": "80"
41
+ }
42
+ }
43
+ }
44
+ }
45
+
46
+ Returns:
47
+ str: The filepath to the generated PNG image file.
48
+ """
49
+ try:
50
+ if not json_input.strip():
51
+ return "Error: Empty input"
52
+
53
+ data = json.loads(json_input)
54
+
55
+ if 'root' not in data:
56
+ raise ValueError("Missing required field: root")
57
+
58
+ dot = graphviz.Digraph(
59
+ name='BinaryTree',
60
+ format='png',
61
+ graph_attr={
62
+ 'rankdir': 'TB', # Top-to-Bottom layout (vertical hierarchy)
63
+ 'splines': 'line', # Straight lines
64
+ 'bgcolor': 'white', # White background
65
+ 'pad': '0.5', # Padding around the graph
66
+ 'nodesep': '0.8', # Spacing between nodes
67
+ 'ranksep': '1.0' # Spacing between levels
68
+ }
69
+ )
70
+
71
+ base_color = '#19191a' # Hardcoded base color
72
+
73
+ def add_binary_tree_nodes(node, current_depth=0):
74
+ """
75
+ Add binary tree nodes recursively with proper styling.
76
+ """
77
+ if not node:
78
+ return
79
+
80
+ node_id = node.get('id', f'node_{current_depth}')
81
+ node_label = node.get('label', 'Node')
82
+
83
+ # Calculate color opacity based on depth
84
+ max_depth = 5 # Assume maximum depth for color calculation
85
+ if current_depth >= max_depth:
86
+ opacity = '80' # Minimum opacity
87
+ else:
88
+ opacity_value = int(255 * (1.0 - (current_depth * 0.6 / max_depth)))
89
+ opacity = format(opacity_value, '02x')
90
+
91
+ node_color = f"{base_color}{opacity}"
92
+ font_color = 'white' if current_depth < 3 else 'black'
93
+
94
+ # Add the current node
95
+ dot.node(
96
+ node_id,
97
+ node_label,
98
+ shape='circle',
99
+ style='filled',
100
+ fillcolor=node_color,
101
+ fontcolor=font_color,
102
+ fontsize='14',
103
+ width='0.8',
104
+ height='0.8'
105
+ )
106
+
107
+ # Process left child
108
+ left_child = node.get('left')
109
+ if left_child:
110
+ add_binary_tree_nodes(left_child, current_depth + 1)
111
+ left_id = left_child.get('id', f'node_{current_depth + 1}_left')
112
+ dot.edge(
113
+ node_id,
114
+ left_id,
115
+ color='#666666',
116
+ arrowsize='0.8'
117
+ )
118
+
119
+ # Process right child
120
+ right_child = node.get('right')
121
+ if right_child:
122
+ add_binary_tree_nodes(right_child, current_depth + 1)
123
+ right_id = right_child.get('id', f'node_{current_depth + 1}_right')
124
+ dot.edge(
125
+ node_id,
126
+ right_id,
127
+ color='#666666',
128
+ arrowsize='0.8'
129
+ )
130
+
131
+ # Add binary tree nodes and edges recursively
132
+ add_binary_tree_nodes(data['root'], current_depth=0)
133
+
134
+ with NamedTemporaryFile(delete=False, suffix=f'.{output_format}') as tmp:
135
+ dot.render(tmp.name, format=output_format, cleanup=True)
136
+ return f"{tmp.name}.{output_format}"
137
+
138
+ except json.JSONDecodeError:
139
+ return "Error: Invalid JSON format"
140
+ except Exception as e:
141
+ return f"Error: {str(e)}"