I am trying to do an N-Ary tree based on Linked-Lists and Nodes. But whenever I try to add a new value to the tree I keep getting:
NameError: name 'self' is not defined
I work with modules so I have to import the classes from other files.
I get this error in def addTree(self, value, parent = self.root): on Tree Code
Tree Code
from Resources.LinkedList import *
class Tree:
def __init__(self):
self.root = LinkedList()
def addTree(self, value, parent = self.root):
parent.addLinkedList(value)
Node Code
from Resources.LinkedList import *
class Node:
def __init__(self,name):
self.name = name
self.children = LinkedList()
self.next = None
Linked-List Code
from Resources.Node import *
from Resources.Compare import *
class LinkedList:
def __init__(self):
self.first = None
def addLinkedList(self,value):
if (not self.first):
self.first = Node(value)
else:
compare = Compare()
if(compare.compare(self.first,value)>0):
stack = self.first
self.first = Node(value)
self.first.next = stack
return True
else:
previous = self.first
current = self.first.next
while(current):
if (compare.compare(current,value)<0):
previous = current
current = current.next
return True
elif (compare.compare(current,value)>0):
stack = current
previous.next = Node(value)
previous.next.next = stack
return True
else:
previous.next = Node(value)
previous.next.next = current.next
return True
previous.next = Node(value)
return True
Also thanks for your help, I'm kinda new to Python and I don't know what I am doing wrong.
The problem is that "self" is only defined within the method and cannot be used in the arguments, the trick in these cases is to use None as an argument and make the verification:
def addTree(self, value, parent = None):
if parent is None:
parent = self.root
parent.addLinkedList(value)
Related
I am trying to implement a doubly linked list with multiple variables (in this case two) per node in Python 3.
First, I created a HashEntry class for it (I'll get to make after this a hash table):
class HashEntry(self):
def __init__(self, key, data, p, n):
self.key = int(key)
self.data = str(data)
self.prev = n
self.next = p
Then I have to use this class for my doubly linked list operations and so, but I'm not sure how to do it, if I have to create another Node class or if I to put the two values for each method
This is what I have tried:
class Node:
def __init__(self, h = HashEntry, p = None, n = None):
# this is where i don't know how to put my hashentry type element
# into the node. i was trying to make it into a single element node.
self.element = h
self.next = n
self.prev = p
class Dlist(self):
def __init__(self):
self.head = None
self.last = None
def insert(self, e):
aux = Node(e, None, None)
if self.head is None:
self.head = self.last
self.head = aux
else:
aux.prev = self.last
aux.next = None
self.last.next = aux
self.last = aux
Thank you a lot.
Except the missing part of HashEntry management, the source code is showing some errors which not allow to execute the software.
Minor Error 1 - a Python class doesn't inherit from self and it is recommended to inherit from the class object.
Class declaration should be:
class HashEntry(object):
class Dlist(object):
Instead of:
class HashEntry(self):
class Dlist(self):
Minor Error 2 - a mixture between self.head and self.last when inserting the first HashEntry in the first linked-list.
The assignment self.head = self.last doesn't work because self.last is not initialize.
aux = Node(e, None, None)
if self.head is None:
# self.head = self.last <= wrong assignement
self.head = aux
self.last = self.head # assign last based to the head
else:
Analysis 1 - add the HashEntry management by using the key.
To create a double linked-list with the simulated hashtable access, the first linked-list has to manage a kind of hashtable and the second linked-list is linked to the first to store all nodes having the same key.
1- Add to the class Dlist a search(self,key) function to check if the key of the node aux = Node(e, None, None) exists in the first linked-list:
The returned value is the HashEntry node of the key otherwise
None.
def search(self,key):
curr = self.head
while (curr is not None):
if (key == curr.element.key):
return (curr)
curr = curr.next
return (None)
2- Add to the class Node a append(self,nwnode) function to add to the second linked-list the node nwnode having the HashEntry.key.
The second list has to header the node element.
def append(self,nwnode):
if (self.element.next is None):
self.element.next = nwnode # adding the first homo-key
nwnode.element.prev = self
else:
curr = self.element.next
while (curr.next is not None):
curr = curr.next
curr.next = nwnode # adding others homo-key
nwnode.element.prev = curr
3- Connect both functions in the insert(self, e) of the class Dlist.
Check if the key is existing when the first linked-list is not
empty.
else:
hashnode = self.search(e.key)
Then insert the new HashEntry aux node in the first linked-list or append it to the second linked-list.
if (hashnode is None):
aux.prev = self.last
aux.next = None
self.last.next = aux # insert to the first linked-list
self.last = aux
else:
hashnode.append(aux) # append to the second linked-list
I have worked with linked lists and classes almost exclusively in c++, so I am having trouble getting this to work. The first class is supposed to have the variables name and next, an init function, two getter functions, and two setter functions. The second class(Line) is supposed to have an init function and an add function that adds items to the end of the linked list. I can't seem to get my add function to work. Any help is appreciated.
This is the code I have so far.
class PersonList():
"""
The class to represent the node in a linked list of people. It takes the variables:
name, which represents the person's name, and next_person, which links the next
person in the linked list.
"""
def __init__(self, name = None, next_ = None):
self.__name = name
self.__next = next_
def getName(self):
return self.__name
def getNext(self):
return self.__next
def setName(self, new_name):
self.__name = new_name
def setNext(self, new_person):
self.__next = new_person
def __str__(self):
return (self.__name)
def printlist(node):
next_node = node.getNext()
while next_node != None:
next_node = node.getNext()
print (node)
node = node.getNext()
class Line():
""" The class that represents the line of people as the linked list. Takes the variable
head, that denotes the first person in the line
"""
def __init__(self, head = None):
self.head = None
def add(self, name):
if self.head == None:
self.head = PersonList(name)
else:
Or just keep track of the tail to avoid traversing the whole list each time you want to add something:
class Line():
""" The class that represents the line of people as the linked list. Takes the variable
head, that denotes the first person in the line
"""
def __init__(self, head = None):
self.head = None
self.tail = None
def add(self, name):
tmp = PersonList(name)
if self.head == None:
self.head = tmp
self.tail = tmp
else:
self.tail.next = tmp
self.tail = tmp
def add(self, name):
if self.head == None:
self.head = PersonList(name)
else:
tmp = self.head
while tmp._next is not None: #while we are not at the end of the line
tmp = tmp._next
#end of line
tmp._next = PersonList(name) #get in line at the end
is one option
I have done the following linked list in python, it works fine, but I was wondering if there is another way to to the part add_item to a linked list. In that part what I want to do is to keep a pointer in the first element, and so adding the elements in front of it, for example:
1
first
1----->2
first
1----->2----->3
first
my code is:
class Node:
def __init__(self,elem=None,next=None):
self.elem=elem
self.next=next
def __repr__(self):
return 'Node(elem={}, next={})'.format(self.elem, self.next)
class LinkedList:
def __init__(self):
self.size=0
self.first=None
self.linkedlist=Node()
def add(self,elem):
node=Node(elem)
if self.size==0:
self.first=node
else:
self.linkedlist.next=node
self.linkedlist=node
self.size=self.size+1
is there another way to perform this behaviour wihout using the auxiliar self.linkedlist that I have in the builder of the LinkedList class?
Thanks
Keep track of last element and always a new node to its next. Then update the last
class Node:
def __init__(self, elem=None, next=None):
self.elem = elem
self.next = next
class LinkedList:
def __init__(self):
self.size = 0
self.first = None
self.last = None
def add(self, elem):
node = Node(elem)
if self.size == 0:
self.first = node
self.first.next = node
self.last = node
else:
self.last.next = node
self.last = node
self.size += 1
I think that something like the following method would work:
class LinkedList:
# what you have so far
def add_to_front(self, elem):
if self.size == 0:
self.add(elem)
else:
node = Node(elem, self.first)
self.first = node
self.size += 1
You currently have a reference to the head of the list in self.first and a reference to the current tail in self.linkedlist. That allows efficient additions at either point.
ll = LinkedList()
for i in xrange(3):
ll.add_to_front(i)
>>> ll.linkedlist
Node(elem=0, next=None)
>>> ll.first
Node(elem=2, next=Node(elem=1, next=Node(elem=0, next=None)))
>>> ll.add('x')
>>> ll.linkedlist
Node(elem=x, next=None)
>>> ll.first
Node(elem=2, next=Node(elem=1, next=Node(elem=0, next=Node(elem=x, next=None))))
>>>
Try this(I've changed the add method only. This doesn't involve the linkedlist class member.) -
class LinkedList:
def __init__(self):
self.size=0
self.first=None
def add(self,elem):
if self.size == 0:
self.first = Node(elem)
else:
self.first = Node(elem, self.first)
self.size += 1
As a first project on OOP I'm working on a linked list oop class, got most of the methods done but the remove node method is not working.
When I run the code I get this error:
AttributeError: 'Node' object has no attribute 'val'
I can't figure out what I'm doing wrong in it!
class Node():
def __init__(self, val):
self.value = val
self.next = None
class Linked_list():
def __init__(self):
self.next = None
nextnode=self.next
def insert(self, val, loc):
p = self
for i in range(0, loc):
p = p.next
tmp = p.next
newNode = Node(val)
p.next = newNode
newNode.next = tmp
def find(self, val):
p = self.next
# loc = 0 # in case we want to return the location
while p != None:
if p.value == val:
return p
else:
p = p.next
#loc=loc+1 # in case we want to return the location
return None
def remove_node(self, node):
current = self.next
previous = None
found = False
while not found:
if current.val == node:
found = True
else:
previous = current
current = current.next
if previous == None:
self.next = current.next
else:
previous.current.next
def __eq__(self, other):
cnt=0
s=self.next
p=other.next
if Linked_list.length(self)!=Linked_list.length(other):
return False
if s.value==p.value:
for i in range(Linked_list.length(self)-1):
p=p.next
s=s.next
if s.value==p.value:
cnt+=1
if cnt==Linked_list.length(self)-1:
return True
else:
return False
Your Node class has an attribute value assigned in the __init__ method, but not an attribute val, hence the error. The confusion probably comes from the fact that the variable you pass to __init__ is called val.
So i solved a couple of problems already, by getting help here, and
from people i know. the root of my problems is that i don't know how to wrap None so
that i don't keep getting these errors of not having the attribute, or not callable.
For this linked list, all i really need is insert and printlist.
I didn't include print list because it is simple, and is not causing problems.
The error is under Linked_List, under insert, under the elif.
It's commented so: #<----ERROR
Here is the code:
class Node:
def __init__(self, word):
self.data = word
self.next = None
def nextNode(self):
if self.next is not None:
return self.next
else:
return None
def getData(self):
return self.data
def setNext(self, node):
self.next = node
def hasNext(self):
if self.next == None:
return False
else:
return True
class Linked_List:
def __init__(self):
self.head = Node(None)
self.isempty = True
def insert(self, word):
newNode = Node(word)
prev = self.head.nextNode()
current = self.head.nextNode()
nextFound = False #the next would be the current when it is less than node
#Look for position to insert:
#When empty
if self.isempty == True:
self.isempty = False
self.head = newNode
#When has more than one
elif self.head.hasNext():
while nextFound == False:
if current.getData() > newNode.getData():
prev = current
current = curent.nextNode()
else:
nextFound = True
#Insert
prev.next().setNext(newNode) # <-------ERROR -----HERE~~
newNode.setNext(current)
else:
#When only has one node not empty
if self.head.getData() > newNode.getData():
self.head.setNext(newNode)
else:
newNode.setNext(self.head)
self.head = newNode
Insertion:
lList.insert(string)
Solved Here:
class Linked_List:
def __init__(self):
self.head = Node(None)
self.isempty = True
def insert(self, word):
newNode = Node(word)
prev = self.head.nextNode()
current = self.head.nextNode()
nextFound = False #the next would be the current when it is less than node
#Look for position to insert:
#When empty
if self.isempty == True:
self.isempty = False
self.head = newNode
#When has more than one
elif self.head.hasNext():
while nextFound == False and current != None:
if current.getData() > newNode.getData():
prev = current
if current.hasNext():
current = current.nextNode()
else:
current = None
else:
nextFound = True
#Insert
prev.setNext(newNode)
newNode.setNext(current)
else:
#When only has one node not empty
if self.head.getData() > newNode.getData():
self.head.setNext(newNode)
else:
newNode.setNext(self.head)
self.head = newNode
How do you use it? I'm guessing that you do something like yourList.insert(1). In your code you do: self.head = node, where node is what user have passed to insert. So, on the next call to insert you end up trying to call an int or anything you've tried to put into the list. You need to wrap any objects given by the user with your Node class:
def insert(self, thing):
node = Node(thing)
//...
However, please remember to post all of the relevant code, so the people trying to help you won't have to guess.
EDIT: still, after the edit the case remains the same. You don't wrap objects passed to your list, so you keep trying to call Node methods on non-Node objects...