, Name "DSABinarySearchTree" is not defined - python

class DSATreeNode:
def __init__(self, data):
self.data = data
self.left = None
self.right = None
class DSABinarySearchTree:
def __init__(self):
self.root = None
def insert(self, data):
if self.root is None:
self.root = DSATreeNode(data)
else:
self._insert(data, self.root)
This line of code is located in one python file
import searchtree
bst = DSABinarySearchTree()
# Test insertion
bst.insert(5)
bst.insert(3)
bst.insert(8)
bst.insert(2)
bst.insert(4)
bst.insert(7)
bst.insert(9)
This line of code is in a different python file.
"searchtree" is the name of the first python file where the "class DSABinarySearchTree" is located. Note that the python program needs to run on the terminal

Related

Anytree NodeMixin

I want to use the NodeMixin Module, but it's not really clear to me if I read the documentation how to do that.
https://anytree.readthedocs.io/en/2.8.0/api/anytree.node.html#anytree.node.nodemixin.NodeMixin
I have a BaseClas like this:
from anytree import NodeMixin, RenderTree
class Tree():
def __init__(self, data, parent):
self.data = data
self.parent = parent
self.children = []
def __eq__(self, other):
if isinstance(other, Tree):
return self.data == other.data
else:
return False
def __repr__(self):
return "Tree("+str(self.data)+","+str(self.children)+")"
def __str__(self):
return self.__repr__()
def update_parent(self, new):
self.parent = new
def add_child(self, c):
self.children.append(c)
def rm_child(self, c):
self.children.remove(c)
If I want to use the NodeMixin Module I would need something like this:
class TreeMix(Tree, NodeMixin): # Add Node feature
def __init__(self, name, length, width, parent=None, children=None):
super(TreeMix, self).__init__()
self.name = name
self.length = length
self.width = width
self.parent = parent
if children:
self.children = children
I get this Error Message:
init() missing 2 required positional arguments: 'data' and 'parent'
I create Objects like this:
my0 = TreeMix('0', 0, 0, parent=None)
my1 = TreeMix('1', 1, 0, parent=my0)
my2 = TreeMix('2', 2, 0, parent=my1)
Did I get the Constructor wrong?

Python class iterator

I have a class of the node which contain his parent and want to create iterator on it. Here is my try:
class Node:
def __init__(self, parent=None):
self._parent = parent
def __iter__(self):
self = self.parent
def __next__(self):
if self.parent is None:
raise StopIteration
else:
self = self.parent
return self
But when I try to loop over the instance, it's never stops and returns the same value, what I did wrong?
The reason your code doesn't work is that you're trying to keep track of the current node in the iterator by assigning to self, which is just a local variable, so nothing is actually updated.
The correct way would be to extract an iterator class and keep track of the current node there:
class Node:
def __init__(self, parent=None):
self.parent = parent
def __iter__(self):
return NodeIterator(self)
class NodeIterator:
def __init__(self, node):
self.next_node = node
def __iter__(self):
return self
def __next__(self):
if self.next_node is None:
raise StopIteration
else:
current_node = self.next_node
self.next_node = self.next_node.parent
return current_node
This can be used like so:
root = Node()
inner_1 = Node(root)
leaf_1 = Node(inner_1)
inner_2 = Node(root)
inner_2_1 = Node(inner_2)
leaf_2 = Node(inner_2_1)
for node in leaf_2:
# will loop through:
# leaf_2,
# inner_2_1;
# inner_2,
# root

Creating python objects of same type from nested class

My List class has a nested _Node class within it. With these 2 classes, I can:
Initialize an object of type List within List.
Initialize an object of type _Node within List.
Initialize an object of type List within _Node.
I can't, however, initialize a _Node within a _Node. The last line of the code is below causes NameError: global name '_Node' is not defined
class List:
def __init__(self):
self.root = None
self.brother = None
def set_root(self):
self.root = self._Node()
def set_brother(self):
self.brother = List()
def set_root_next(self):
self.root.set_next()
class _Node:
def __init__(self, next_node=None, data=None):
self.next_node = next_node
self.data = data
def set_next(self):
self.next_node = _Node()
if __name__ == '__main__':
x = List()
x.set_root()
x.set_brother()
x.set_root_next()
How do I solve this? Making the _Node class unnested works but I am planning to have many types of list in the same file. All accompanying nodes will inherit from a single abstract class so keeping this structure is important.
Try using self.__class__() instead
class List:
def __init__(self):
self.root = None
self.brother = None
def set_root(self):
self.root = self._Node()
def set_brother(self):
self.brother = List()
def set_root_next(self):
self.root.set_next()
class _Node:
def __init__(self, next_node=None, data=None):
self.next_node = next_node
self.data = data
def set_next(self):
self.next_node = self.__class__()
if __name__ == '__main__':
x = List()
x.set_root()
x.set_brother()
x.set_root_next()

Python Linked List with Nodes. Iterable

I need some help writing an __iter__() method for my UnorderedList() class. I tried this:
def __iter__(self):
current = self
while current != None:
yield current
But the while loop doesn't stop. Here is the rest of my classes and code:
class Node:
def __init__(self,initdata):
self.data = initdata
self.next = None
def getData(self):
return self.data
def getNext(self):
return self.next
def setData(self,newdata):
self.data = newdata
def setNext(self,newnext):
self.next = newnext
class UnorderedList:
def __init__(self):
self.head = None
self.count = 0
If you want to iterate all items succeedingly, you should do
def __iter__(self):
# Remember, self is our UnorderedList.
# In order to get to the first Node, we must do
current = self.head
# and then, until we have reached the end:
while current is not None:
yield current
# in order to get from one Node to the next one:
current = current.next
so that in every step you go one step further.
BTW, setters and getters aren't used in Python in the form of methods. If you need them, use properties, otherwise omit them altogether.
So just do
class Node(object):
def __init__(self, initdata):
self.data = initdata
self.next = None
class UnorderedList(object):
def __init__(self):
self.head = None
self.count = 0
def __iter__(self):
current = self.head
while current is not None:
yield current
current = current.next

Readline feature in Directory Lister class

The below class is a dynamic attribute generating directory walker by Anurag.
import os
class DirLister(object):
def __init__(self, root):
self.root = root
self._list = None
def __getattr__(self, name):
try:
var = super(DirLister).__getattr__(self, name)
return var
except AttributeError:
return DirLister(os.path.join(self.root, name))
def __str__(self):
self._load()
return str(self._list)
def _load(self):
"""
load once when needed
"""
if self._list is not None:
return
self._list = os.listdir(self.root) # list root someway
root = DirLister("/")
print root.etc.apache
Is there a way to add other complex functions to the DirLister by Anurag above? So when it gets to a file say testdir/j/p, it prints out the first line of file p.
[IN] print testdir.j.p
[OUT] First Line of p
I have made a class for printing out the first line of the file:
class File:
def __init__(self, path):
"""Read the first line in desired path"""
self.path = path
f = open(path, 'r')
self.first_line = f.readline()
f.close()
def __repr__(self):
"""Display the first line"""
return self.first_line
Just need to know how to incorporate it in the class below. Thank you.
You should be able to accomplish this by checking to see if self.root is a file or a directory in _load(). Read the first line if it is a file and do os.listdir() if it is a directory. Try the following:
import os
class DirLister(object):
def __init__(self, root):
self.root = root
self._data = None
def __getattr__(self, name):
try:
var = super(DirLister).__getattr__(self, name)
return var
except AttributeError:
return DirLister(os.path.join(self.root, name))
def __str__(self):
self._load()
return str(self._data)
def _load(self):
"""
load once when needed
"""
if self._data is not None:
return
if os.path.isfile(self.root):
f = File(self.data)
self._data = f.first_line
else:
self._data = os.listdir(self.root) # list root someway
I used your File class, but you could also just put the code for getting the first line in _load() instead of having a separate class to do it. Note that I also renamed _list to _data, since it will not always represent a list of files anymore.

Categories