diff --git a/ast/ast_generator.py b/ast/ast_generator.py
new file mode 100644
index 0000000000000000000000000000000000000000..97d790a615fed8ece98adfb5bffa6a850b032b85
--- /dev/null
+++ b/ast/ast_generator.py
@@ -0,0 +1,48 @@
+import ast
+import sys 
+import pprint
+from graphviz import Digraph
+
+
+def main():
+  if len(sys.argv) != 2:
+    exit()
+  file_name = sys.argv[1]
+  with open(file_name, 'r') as file:
+    data = file.read()
+  tree = ast.parse(data)
+
+  pprint.pprint(ast.dump(tree))
+
+  # Create a Graphviz Digraph object
+  dot = Digraph()
+
+  def add_node(node2, parent=None):
+    node_name = str(node2.__class__.__name__)
+    dot.node(str(id(node2)), node_name)
+    if parent:
+        dot.edge(str(id(parent)), str(id(node2)))
+    for child in ast.iter_child_nodes(node2):
+        add_node(child, node2)
+  
+  add_node(tree)
+
+  # Render the Digraph as a PNG file
+  dot.format = 'png'
+  dot.render('my_ast', view=True)
+
+
+if __name__ == "__main__":
+  main()
+
+
+import ast
+from graphviz import Digraph
+
+...
+
+
+# Define a function to recursively add nodes to the Digraph
+
+
+# Add nodes to the Digraph
diff --git a/ast/astvisualizer.py b/ast/astvisualizer.py
new file mode 100644
index 0000000000000000000000000000000000000000..9bac88b6629ca3ea29a458f83808236eea1d6f56
--- /dev/null
+++ b/ast/astvisualizer.py
@@ -0,0 +1,143 @@
+import ast
+from graphviz import Digraph
+import subprocess
+import numbers
+import re
+from uuid import uuid4 as uuid
+import optparse
+import sys
+
+def main(args):
+    parser = optparse.OptionParser(usage="astvisualizer.py [options] [string]")
+    parser.add_option("-f", "--file", action="store",
+                      help="Read a code snippet from the specified file")
+    parser.add_option("-l", "--label", action="store",
+                      help="The label for the visualization")
+
+    options, args = parser.parse_args(args)
+    if options.file:
+        with open(options.file) as instream:
+            code = instream.read()
+        label = options.file
+    elif len(args) == 2:
+        code = args[1]
+        label = "<code read from command line parameter>"
+    else:
+        print("Expecting Python code on stdin...")
+        code = sys.stdin.read()
+        label = "<code read from stdin>"
+    if options.label:
+        label = options.label
+
+    code_ast = ast.parse(code)
+    transformed_ast = transform_ast(code_ast)
+
+    renderer = GraphRenderer()
+    renderer.render(transformed_ast, label=label)
+
+
+def transform_ast(code_ast):
+    if isinstance(code_ast, ast.AST):
+        node = {to_camelcase(k): transform_ast(getattr(code_ast, k)) for k in code_ast._fields}
+        node['node_type'] = to_camelcase(code_ast.__class__.__name__)
+        return node
+    elif isinstance(code_ast, list):
+        return [transform_ast(el) for el in code_ast]
+    else:
+        return code_ast
+
+
+def to_camelcase(string):
+    return re.sub('([a-z0-9])([A-Z])', r'\1_\2', string).lower()
+
+
+class GraphRenderer:
+    """
+    this class is capable of rendering data structures consisting of
+    dicts and lists as a graph using graphviz
+    """
+
+    graphattrs = {
+        'labelloc': 't',
+        'fontcolor': 'white',
+        'bgcolor': '#333333',
+        'margin': '0',
+    }
+
+    nodeattrs = {
+        'color': 'white',
+        'fontcolor': 'white',
+        'style': 'filled',
+        'fillcolor': '#006699',
+    }
+
+    edgeattrs = {
+        'color': 'white',
+        'fontcolor': 'white',
+    }
+
+    _graph = None
+    _rendered_nodes = None
+
+
+    @staticmethod
+    def _escape_dot_label(str):
+        return str.replace("\\", "\\\\").replace("|", "\\|").replace("<", "\\<").replace(">", "\\>")
+
+
+    def _render_node(self, node):
+        if isinstance(node, (str, numbers.Number)) or node is None:
+            node_id = uuid()
+        else:
+            node_id = id(node)
+        node_id = str(node_id)
+
+        if node_id not in self._rendered_nodes:
+            self._rendered_nodes.add(node_id)
+            if isinstance(node, dict):
+                self._render_dict(node, node_id)
+            elif isinstance(node, list):
+                self._render_list(node, node_id)
+            else:
+                self._graph.node(node_id, label=self._escape_dot_label(str(node)))
+
+        return node_id
+
+
+    def _render_dict(self, node, node_id):
+        self._graph.node(node_id, label=node.get("node_type", "[dict]"))
+        for key, value in node.items():
+            if key == "node_type":
+                continue
+            child_node_id = self._render_node(value)
+            self._graph.edge(node_id, child_node_id, label=self._escape_dot_label(key))
+
+
+    def _render_list(self, node, node_id):
+        self._graph.node(node_id, label="[list]")
+        for idx, value in enumerate(node):
+            child_node_id = self._render_node(value)
+            self._graph.edge(node_id, child_node_id, label=self._escape_dot_label(str(idx)))
+
+
+    def render(self, data, *, label=None):
+        # create the graph
+        graphattrs = self.graphattrs.copy()
+        if label is not None:
+            graphattrs['label'] = self._escape_dot_label(label)
+        graph = Digraph(graph_attr = graphattrs, node_attr = self.nodeattrs, edge_attr = self.edgeattrs)
+
+        # recursively draw all the nodes and edges
+        self._graph = graph
+        self._rendered_nodes = set()
+        self._render_node(data)
+        self._graph = None
+        self._rendered_nodes = None
+
+        # display the graph
+        graph.format = "png"
+        graph.render('my_ast', view=False)
+        # subprocess.Popen(['xdg-open', "my_ast.pdf"])
+
+if __name__ == '__main__':
+    main(sys.argv)
\ No newline at end of file
diff --git a/ast/visualizer.py b/ast/visualizer.py
new file mode 100644
index 0000000000000000000000000000000000000000..22e7a2b301ae0afc2da1810baf4afc474ce872dc
--- /dev/null
+++ b/ast/visualizer.py
@@ -0,0 +1,23 @@
+import ast
+from graphviz import Digraph
+
+def visualize(tree):
+  
+  # Create a Graphviz Digraph object
+  dot = Digraph()
+  # Add nodes to the Digraph
+  add_node(dot, tree)
+
+  # Render the Digraph as a PNG file
+  dot.format = 'png'
+  dot.render('my_ast', view=True)
+
+# Define a function to recursively add nodes to the Digraph
+def add_node(dot: Digraph, node, parent=None):
+    node_name = str(node.__class__.__name__)
+    dot.node(str(id(node)), node_name)
+    if parent:
+        dot.edge(str(id(parent)), str(id(node)))
+    for child in ast.iter_child_nodes(node):
+        add_node(child, node)
+