Class Representation of Half Adder Circuit - python

I'm working through this book and am trying to extend its code to make a half adder and eventually a full adder.
I think I should be implementing a way to return the carry and bits from the half adder separately to facilitate connection to later gates. However, that's where I'm blanking. I also need some way to call performGateLogic on the HalfAdder and 'pipe' the inputs to both the XorGate and AndGate and have tried so with Connectors. My brain is just being tied in a pretzel over the method calling and class relations here and I'd appreciate someone straightening it out.
class LogicGate:
def __init__(self,n):
self.name = n
self.output = None
def getName(self):
return self.name
def getOutput(self):
self.output = self.performGateLogic()
return self.output
class BinaryGate(LogicGate):
def __init__(self,n):
LogicGate.__init__(self,n)
self.pinA = None
self.pinB = None
def getPinA(self):
if self.pinA == None:
return int(input("Enter Pin A input for gate "+self.getName()+"-->"))
else:
return self.pinA.getFrom().getOutput()
def getPinB(self):
if self.pinB == None:
return int(input("Enter Pin B input for gate "+self.getName()+"-->"))
else:
return self.pinB.getFrom().getOutput()
def setNextPin(self,source):
if self.pinA == None:
self.pinA = source
else:
if self.pinB == None:
self.pinB = source
else:
print("Cannot Connect: NO EMPTY PINS on this gate")
class AndGate(BinaryGate):
def __init__(self,n):
BinaryGate.__init__(self,n)
def performGateLogic(self):
a = self.getPinA()
b = self.getPinB()
if a==1 and b==1:
return 1
else:
return 0
class XorGate(BinaryGate):
def __init__(self,n):
BinaryGate.__init__(self,n)
def performGateLogic(self):
a = self.getPinA()
b = self.getPinB()
if (a ==1 and b==0) or (a==0 and b==1):
return 1
else:
return 0
class Connector:
def __init__(self, fgate, tgate):
self.fromgate = fgate
self.togate = tgate
tgate.setNextPin(self)
def getFrom(self):
return self.fromgate
def getTo(self):
return self.togate
class HalfAdder(BinaryGate):
def __init__(self,n):
BinaryGate.__init__(self,n)
self.bits, self.carry = None, None
self.a, self.b = None, None
self.xor = XorGate('XO')
self.and_ = AndGate('A')
self.c1 = Connector(self.xor.getPinA(), self.and_.getPinA())
self.c2 = Connector(self.xor.getPinB(), self.and_.getPinB())
def performGateLogic(self):
self.a = self.getPinA()
self.b = self.getPinB()
self.bits = 1 if (self.a ==1 and self.b==0) or (self.a==0 and self.b==1) else 0
self.carry = 1 if (self.a==1 and self.b ==1) else 0
return self.bits + self.carry
Running print(HalfAdder('HA').getOutput()) yields
File "./circuits.py", line 178, in __init__
self.c1 = Connector(self.xor.getPinA(), self.and_.getPinA())
File "./circuits.py", line 161, in __init__
tgate.setNextPin(self)
AttributeError: 'int' object has no attribute 'setNextPin'
Something is being set to an int but where, I can't find.

Related

Is there a way to have a object type of your choice (i.e. LinkedEdge) hash as part of a 'union.set()' processing?

I have the following code and it works until it gets to the 'union.set()' part. It says, "unhashable type: 'LinkedEdge' " . I am not sure why this is the case since I have looked at other sources on the web and in reference books to know that the 'g.addVertex()' method and the 'g.addEdge()' method as well as the arguments being passed should lead correctly to an output like this:
5 Vertices: A C B E D
5 Edges: A>B:3 A>C:2 B>D:1 C>D:1 D>E:2
class LinkedEdge(object):
def __init__(self, fromVertex, toVertex, weight = None):
self._vertex1 = fromVertex
self._vertex2 = toVertex
self._weight = weight
self._mark = False
def clearMark(self):
self._mark = False
def __eq__(self, other):
if self is other: return True
if type(self) != type(other):
return False
return self._vertex1 == other._vertex1 and self._vertex2 == other._vertex2
def getOtherVertex(self, thisVertex):
if thisVertex == None or thisVertex == self._vertex2:
return self._vertex1
else:
return self._vertex2
def getToVertex(self):
return self._vertex2
def getWeight(self):
return self._weight
def isMarked(self):
return self._mark
def setMark(self):
self._mark = True
def setWeight(self, weight):
self._weight = weight
def __str__(self):
return str(self._vertex1) + ">" + str(self._vertex2) + ":" + str(self._weight)
class LinkedVertex(object):
def __init__(self, label):
self._label = label
self._edgeList = []
self._mark = False
def clearMark(self):
self._mark = False;
def getLabel(self):
return self._label
def isMarked(self):
return self._mark
def setLabel(self, label, g):
g._vertices.pop(self._label, None)
g._vertices[label] = self
self._label = label
def setMark(self):
self._mark = True
def __str__(self):
return str(self._label)
def addEdgeTo(self, toVertex, weight):
edge = LinkedEdge(self, toVertex, weight)
self._edgeList.append(edge)
def getEdgeTo(self, toVertex):
edge = LinkedEdge(self, toVertex)
try:
return self._edgeList[self._edgeList.index(edge)]
except:
return None
def incidentEdges(self):
return iter(self._edgeList)
def neighboringVertices(self):
vertices = []
for edge in self._edgeList:
vertices.append(edge.getOtherVertex(self))
return iter(vertices)
def removeEdgeTo(self, toVertex):
edge = LinkedEdge(self, toVertex)
if edge in self._edgeList:
self._edgeList.remove(edge)
return True
else:
return False
class LinkedDirectedGraph(object):
def __init__(self, collection = None):
self._vertexCount = 0
self._edgeCount = 0
self._vertices = {}
if collection != None:
for label in collection:
self.addVertex(label)
# Methods for clearing, marks, sizes, string rep
def clear(self):
self._vertexCount = 0
self._edgeCount = 0
self._vertices = {}
def clearEdgeMarks(self):
for edge in self.edges():
edge.clearMark()
def clearVertexMarks(self):
for vertex in self.vertices():
vertex.clearMark()
def isEmpty(self):
return self._vertexCount == 0;
def sizeEdges(self):
return self._edgeCount
def sizeVertices(self):
return self._vertexCount
def __str__(self):
result = str(self.sizeVertices()) + " Vertices: "
for vertex in self._vertices:
result += " " + str(vertex)
result += "\n";
result += str(self.sizeEdges()) + " Edges: "
for edge in self.edges():
result += " " + str(edge)
return result
def addVertex(self, label):
self._vertices[label] = LinkedVertex(label)
self._vertexCount += 1
def containsVertex (self, label):
return label in self._vertices
def getVertex(self, label):
return self._vertices[label]
def removeVertex(self, label):
removedVertex = self._vertices.pop(label, None)
if removedVertex is None:
return False
# Examine all vertices
for vertex in self.vertices():
if vertex.removeEdgeTo(removedVertex):
self._edgeCount -= 1
self._vertexCount -= 1
return True
def addEdge(self, fromLabel, toLabel, weight):
fromVertex = self.getVertex(fromLabel)
toVertex = self.getVertex(toLabel)
fromVertex.addEdgeTo(toVertex, weight)
self._edgeCount += 1
def containsEdge(self, fromLabel, toLabel):
return self.getEdge(fromLabel, toLabel) != None
def getEdge(self, fromLabel, toLabel):
fromVertex = self._vertices[fromLabel]
toVertex = self._vertices[toLabel]
return fromVertex.getEdgeTo(toVertex)
def removeEdge (self, fromLabel, toLabel):
fromVertex = self.getVertex(fromLabel)
toVertex = self.getVertex(toLabel)
edgeRemovedFlg = fromVertex.removeEdgeTo(toVertex)
if edgeRemovedFlg:
self._edgeCount -= 1
return edgeRemovedFlg
# Iterators
def edges(self):
result = set()
for vertex in self.vertices():
edges = vertex.incidentEdges()
result = result.union(set(edges))
return iter(result)
def vertices(self):
return iter(self._vertices.values())
def incidentEdges(self, label):
return self._vertices[label].incidentEdges()
def neighboringVertices(self, label):
return self._vertices[label].neighboringVertices
g = LinkedDirectedGraph()
# Insert vertices
g.addVertex("John")
g.addVertex("Sam")
g.addVertex("Megan")
g.addVertex("Jennifer")
g.addVertex("Rick")
# Insert weighted edges
g.addEdge("John", "Sam", 3)
g.addEdge("John", "Megan", 2)
g.addEdge("Sam", "Jennifer", 1)
g.addEdge("Megan", "Jennifer", 1)
g.addEdge("Jennifer", "Rick", 2)
print(g)
If you override __eq__, then Python intentionally makes your class unhashable, since there is no longer a guarantee that the default hashing algorithm (based on the object's location in memory) is compatible with your __eq__ algorithm. "Compatible" here just means that equal objects must have equal hashes. By default, nothing is equal, so when you make some things equal using an __eq__ method, you impose a requirement on what a proper hash function must do.
If you want a custom class with a custom __eq__ method to be hashable, you must implement a __hash__ method yourself.
It could be as simple as being based on the hash of the corresponding tuple:
def __hash__(self):
return hash((type(self), self._vertex1, self._vertex2))
The Python docs explain this here.

Abstract decorator, error in retransmission to subclass

I try to realise decorator-pattern. Hero is the main class which can't change, then I have AbstractEffects which is a subclass of Hero and parent class to AbstractNegative and AbstractPositive.
From thE other side AbstractNegative and AbstractPositive are the parent class for Curse, Berserk and others.
from abc import ABC, abstractmethod
class Hero():
def __init__(self):
self.positive_effects = []
self.negative_effects = []
self.stats = {
"HP": 128, # health points
"MP": 42, # magic points,
"SP": 100, # skill points
"Strength": 15, # сила
"Perception": 4, # восприятие
"Endurance": 8, # выносливость
"Charisma": 2, # харизма
"Intelligence": 3, # интеллект
"Agility": 8, # ловкость
"Luck": 1 # удача
}
def get_positive_effects(self):
return self.positive_effects.copy()
def get_negative_effects(self):
return self.negative_effects.copy()
def get_stats(self):
return self.stats.copy()
class AbstractEffects(ABC, Hero):
def __init__(self, base):
self.base = base
#abstractmethod
def get_positive_effects(self):
return self.positive_effects.copy()
#abstractmethod
def get_negative_effects(self):
return self.negative_effects.copy()
#abstractmethod
def get_stats(self):
return self.stats.copy()
class AbstractPositive(AbstractEffects):
def get_positive_effects(self):
return self.base.positive_effects.copy()
def get_negative_effects(self):
return self.base.negative_effects.copy()
class AbstractNegative(AbstractEffects):
def get_positive_effects(self):
return self.base.positive_effects.copy()
def get_negative_effects(self):
return self.base.negative_effects.copy()
class Berserk(AbstractEffects):
def get_stats(self):
self.base.stats["Strength"] = int(self.base.stats["Strength"]) + 2
self.base.stats["Endurance"] = int(self.base.stats["Endurance"]) + 7
self.base.stats["Agility"] = int(self.base.stats["Agility"]) + 7
self.base.stats["Luck"] = int(self.base.stats["Luck"]) + 7
self.base.stats["Perception"] = int(self.base.stats["Perception"]) - 3
self.base.stats["Charisma"] = int(self.base.stats["Charisma"]) - 3
self.base.stats["Intelligence"] = int(self.base.stats["Intelligence"]) - 3
self.base.stats["HP"] = int(self.base.stats["HP"]) + 50
return self.base.stats.copy()
def get_positive_effects(self):
self.base.positive_effects.append("Blessing")
return self.base.positive_effects.copy()
def get_negative_effects(self):
try:
return self.base.negative_effects.pop()
except:
return self.base.negative_effects.copy()
class Blessing(AbstractPositive):
def get_stats(self):
self.base.state["Strength"] = int(self.base.state["Strength"]) + 2
self.base.state["Endurance"] = int(self.base.state["Endurance"]) +2
self.base.state["Agility"] = int(self.base.state["Agility"]) + 2
self.base.state["Luck"] = int(self.base.state["Luck"]) + 2
self.base.state["Perception"] = int(self.base.state["Perception"]) + 2
self.base.state["Charisma"] = int(self.base.state["Charisma"]) + 2
self.base.state["Intelligence"] = int(self.base.state["Intelligence"]) + 2
return self.base.state.copy()
def get_positive_effects(self):
self.base.positive_effects.append("Blessing")
return self.basepositive_effects.copy()
def get_negative_effects(self):
try:
return self.base.negative_effects.pop()
except:
return self.base.negative_effects.copy()
class Weakness(AbstractNegative):
def __init__(self, obj):
self.base.stats = obj.copy()
def get_stats(self):
self.base.stats["Strength"] = int(self.base.stats["Strength"]) - 4
self.base.stats["Endurance"] = int(self.base.stats["Endurance"]) - 4
self.base.stats["Luck"] = int(self.base.stats["Luck"]) - 4
return self.base.stats.copy
def get_positive_effects(self):
try:
return self.base.positive_effects.pop()
except:
return self.base.positive_effects.copy()
def get_negative_effects(self):
self.base.stats.negative_effects.append("Weaknes")
return self.base.stats.negative_effects.copy()
class EvilEye(AbstractNegative):
def get_stats(self):
self.base.stats["Luck"] = int(self.base.stats["Luck"]) - 10
return self.base.stats.copy()
def get_positive_effects(self):
try:
return self.base.positive_effects.pop()
except:
return self.base.positive_effects.copy()
def get_negative_effects(self):
self.base.negative_effects.append("EvilEye")
return self.base.negative_effects.copy()
class Curse(AbstractNegative):
def get_stats(self):
self.base.stats["Strength"] = int(self.base.stats["Strength"]) - 2
self.base.stats["Endurance"] = int(self.base.stats["Endurance"]) -2
self.base.stats["Agility"] = int(self.base.stats["Agility"]) - 2
self.base.stats["Luck"] = int(self.base.stats["Luck"]) - 2
self.base.stats["Perception"] = int(self.base.stats["Perception"]) - 2
self.base.stats["Charisma"] = int(self.base.stats["Charisma"]) - 2
self.base.stats["Intelligence"] = int(self.base.stats["Intelligence"]) - 2
return self.base.stats.copy()
def get_positive_effects(self):
try:
return self.base.positive_effects.pop()
except:
return self.base.positive_effects.copy()
def get_negative_effects(self):
self.base.stats.negative_effects.append("Curse")
return self.base.stats.negative_effects.copy()
When i try to do this
hero = Hero()
hero.get_stats()
brs1 = Berserk(hero)
brs1.get_stats()
brs2 = Berserk(brs1)
cur1 = Curse(brs2)
cur1.get_stats()
I have this error: "AttributeError: 'Berserk' object has no attribute 'stats'"
I can't understend how to fix this error.
If you define the __init__ method of a subclass of Hero, it needs to call the __init__ method of Hero, the superclass, in order to initialize attributes defined by Hero.__init__, including stats in this case:
class Berserk(Hero):
def __init__(self):
super().__init__()
# additional initialization for a Berserk instance

Instance method is not working from an object while it works perefctly from its class

This is the most strange error that I got since I started to program with Python years ago.
First, theses are my classes (Sorry for the long code):
class Quran(Iterable):
def __init__(self):
self.sourats = []
def __iadd__(self, other):
# There is some code here
pass
def __getitem__(self, sourat_num):
if not (isinstance(sourat_num, int) or isinstance(sourat_num, slice)):
raise TypeError('Indexing Quran can be done only using ints or slices')
if isinstance(sourat_num, int):
sourat_num -= 1
else:
sourat_num = slice(sourat_num.start - 1, sourat_num.stop)
try:
return self.sourats[sourat_num]
except IndexError:
return None
def __len__(self):
return len(self.sourats)
# Other methods ...
class Sourat(Iterable):
sourats_titles = [ # 114 strs here
]
def __init__(self, number, quran):
if not isinstance(number, int):
raise TypeError('number must be int')
if not isinstance(quran, Quran):
raise TypeError('quran must be Quran')
self.num = number
self.ayats = []
self.quran = quran
def __int__(self):
return self.num
def __iadd__(self, other):
# Some code here
pass
def __getitem__(self, ayat_num):
if not (isinstance(ayat_num, int) or isinstance(ayat_num, slice)):
raise TypeError('Indexing Sourat can be done only using ints or slices')
if isinstance(ayat_num, int):
ayat_num -= 1
else:
ayat_num = slice(ayat_num.start-1, ayat_num.stop)
try:
return self.ayats[ayat_num]
except IndexError:
return None
def __len__(self):
return len(self.ayats)
def location(self):
return self.num
def previous(self):
p_num = self.num-1
if p_num < 1:
return None
return self.quran[p_num]
def next(self):
n_num = self.num+1
if n_num > len(self.quran):
return None
return self.quran[n_num]
# Other methods ...
class Word(Iterable):
def __init__(self, number, text, features, ayat):
if not isinstance(number, int):
raise TypeError('number must be int')
if not isinstance(text, str):
raise TypeError('text must be str')
if not (isinstance(features, dict) and features['type'] in ('PREFIX', 'STEM', 'SUFFIX')):
raise TypeError('features[type] must be one of PREFIX, STEM, SUFFIX')
if not isinstance(ayat, Ayat):
raise TypeError('ayat must be Ayat')
self.num = number
self.text = text
self.root = features.get('ROOT', None)
self.lem = features.get('LEM', None)
self.type = features['type']
self.next = None
self.previous = None
self.ayat = ayat
def __iadd__(self, other):
# Some code here
def __hash__(self):
# Some code here
pass
def previous(self):
p_num = self.num-1
if p_num < 1:
previous_ayat = self.ayat.previous()
if previous_ayat:
return previous_ayat[-1]
else:
return None
return self.ayat[p_num]
def next(self):
n_num = self.num+1
if n_num > len(self.ayat):
next_ayat = self.ayat.next()
if next_ayat:
return next_ayat[0]
else:
return None
return self.ayat[n_num]
# Other methods ...
And this is what I am have in the main code :
quran_last_14_sourats = parse_quranic_corpus('quranic-corpus-morphology-0.4-last-14-sourats.txt')
sourat = quran_last_14_sourats[2]
ayat = sourat[2]
word = ayat[1]
assert isinstance(ayat, Ayat)
assert isinstance(word, Word)
print(ayat.previous())
print(ayat)
print(ayat.next())
print(Word.next(word)) # This works !!!
print(word.next()) # This doesn't work !!!
My problem is in the next(self) and previous(self) in the class Word, everything else works perfectly.
When I try to use word.next() or word.previous(), it complains that NoneType is not callable. I tried to print(word.next) and it showed None, but this is not logical because these two methods are inside the class Word. This problem doesn't happen in classes Sourat and Ayat even that they have the same structure. And the most crazy thing is that Word.next(word) works without any problem !
Is this a bug in Python 3 ? (BTW I am using the latest version: 3.5.2)
Is this a bug in Python 3 ?
In a word, no.
Instance members and instance methods share the same namespace. Thus, your line in Word.__init__():
self.next = None
obliterates the reference to the method Word.next() inside the newly-allocated Word object.

Visitor pattern (from bottom to top)

Please consider the (example) code below before I get to my specific question regarding visitor pattern in python:
class Node:
def __init__(self):
self.children = []
def add(self, node):
self.children.append(node)
def check(self):
print("Node")
return True
def accept(self, visitor):
visitor.visit(self)
class NodeA(Node):
def check(self):
print("NodeA")
return True
class NodeB(Node):
def check(self):
print("NodeB")
return True
class NodeA_A(NodeA):
def check(self):
print("NodeA_A")
return True
class NodeA_B(NodeA):
def check(self):
print("NodeA_B")
return True
class NodeA_A_A(NodeA_A):
def check(self):
print("NodeA_A_A")
return False
class NodeRunner:
def visit(self, node):
node.check()
if len(node.children) > 0:
for child in node.children:
child.accept(self)
if __name__ == "__main__":
n = Node()
n1 = NodeA()
n2 = NodeB()
n11 = NodeA_A()
n12 = NodeA_B()
n111 = NodeA_A_A()
n.add(n1)
n.add(n2)
n1.add(n11)
n1.add(n12)
n11.add(n111)
v = NodeRunner()
v.visit(n)
When I run it, it traverse all the nodes-classes iteratively and returns the following:
Node
NodeA
NodeA_A
NodeA_A_A
NodeA_B
NodeB
This is all fine but now to my question. You may have noticed that each check-method returns a Boolean (lets say this is a complicated method in reality).
In the example above every check-method inside Node classes return True except NodeA_A_A. I would like to store this somehow during visiting so I can fail all the base classes.
This is hard to explain let me illustrate:
if NodeA_A_A returns False, then I would like to fail NodeA_A, NodeA and Node. regardless of what these classes return.
if NodeB returns False, then I would like to fail Node. regardless of what other classes return.
So if a child-class is somewhere failing (check method returns False), I would like to fail all its base classes.
Does anyone have any ideas?
It seems that what you are asking for is not about visitor patter, but about how to implement a depth-first search algorithm. Here is my solution for your question:
class Node:
def __init__(self):
self.children = []
def add(self, node):
self.children.append(node)
def check(self):
print("Node")
return True
def accept(self, visitor):
return visitor.visit(self)
class NodeA(Node):
def check(self):
print("NodeA")
return True
class NodeB(Node):
def check(self):
print("NodeB")
return True
class NodeA_A(NodeA):
def check(self):
print("NodeA_A")
return True
class NodeA_B(NodeA):
def check(self):
print("NodeA_B")
return True
class NodeA_A_A(NodeA_A):
def check(self):
print("NodeA_A_A")
return False
class NodeRunner:
def visit(self, node):
ret = True
# visit all children
for child in node.children:
v = child.accept(self)
if not v and ret: # if some child not accepted, then we think that the parent node should also not be accepted
ret = False
# check the node
if not node.check():
ret = False
return ret
if __name__ == "__main__":
n = Node()
n1 = NodeA()
n2 = NodeB()
n11 = NodeA_A()
n12 = NodeA_B()
n111 = NodeA_A_A()
n.add(n1)
n.add(n2)
n1.add(n11)
n1.add(n12)
n11.add(n111)
v = NodeRunner()
print v.visit(n)
I used the visitor pattern to visit all the nodes.
One visitor visits and runs all the nodes, the other visitor bubbles up the result.
The code and output is provided below:
class Node(object):
def __init__(self):
self.children = []
self.result = None
def add(self, node):
self.children.append(node)
def check(self):
self.result = True
print "Node: result:%s" % self.result
return self.result
def accept(self, visitor):
visitor.visit(self)
class Node_A(Node):
def __init__(self):
super(Node_A, self).__init__()
def check(self):
self.result = True
print "Node_A: result:%s" % self.result
return self.result
class Node_A_A(Node_A):
def __init__(self):
super(Node_A_A, self).__init__()
def check(self):
self.result = True
print "Node_A_A: result:%s" % self.result
return self.result
class Node_A_B(Node_A):
def __init__(self):
super(Node_A_B, self).__init__()
def check(self):
self.result = True
print "Node_A_B: result:%s" % self.result
return self.result
class Node_A_A_A(Node_A_A):
def __init__(self):
super(Node_A_A_A, self).__init__()
def check(self):
self.result = True
print "Node_A_A_A: result:%s" % self.result
return self.result
class Node_A_A_B(Node_A_A):
def __init__(self):
super(Node_A_A_B, self).__init__()
def check(self):
self.result = False
print "Node_A_A_B: result:%s" % self.result
return self.result
class Node_A_B_A(Node_A_B):
def __init__(self):
super(Node_A_B_A, self).__init__()
def check(self):
self.result = True
print "Node_A_B_A: result:%s" % self.result
return self.result
class NodeRunner:
def visit(self, node):
if len(node.children) > 0:
for child in node.children:
child.accept(self)
node.check()
class NodeChecker:
def visit(self, node):
results = []
if len(node.children) > 0:
for child in node.children:
child.accept(self)
results.append(child.result)
node.result = all(results)
if __name__ == "__main__":
node = Node()
node_a = Node_A()
node_a_a = Node_A_A()
node_a_b = Node_A_B()
node_a_a_a = Node_A_A_A()
node_a_a_b = Node_A_A_B()
node_a_b_a = Node_A_B_A()
node.add(node_a)
node_a.add(node_a_a)
node_a_a.add(node_a_a_a)
node_a_a.add(node_a_a_b)
node_a.add(node_a_b)
node_a_b.add(node_a_b_a)
print("-------------------")
nVisitor = NodeRunner()
nVisitor.visit(node)
print("-------------------")
nVisitor = NodeChecker()
nVisitor.visit(node)
print("-------------------")
print "node_a_a_a: result: %s" % node_a_a_a.result
print "node_a_a_b: result: %s" % node_a_a_b.result
print "node_a_a: result: %s" % node_a_a.result
print "node_a_b_a: result: %s" % node_a_b_a.result
print "node_a_b: result: %s" % node_a_b.result
print "node_a: result: %s" % node_a.result
print "node: result: %s" % node.result
The output is provided below:
-------------------
Node_A_A_A: result:True
Node_A_A_B: result:False
Node_A_A: result:True
Node_A_B_A: result:True
Node_A_B: result:True
Node_A: result:True
Node: result:True
-------------------
-------------------
node_a_a_a: result: True
node_a_a_b: result: False
node_a_a: result: False
node_a_b_a: result: True
node_a_b: result: True
node_a: result: False
node: result: False

Long-double-linked-list

I have a problem with the code. The code gives an error and it says that Node does not have a "previous" in the __add__() operator however it doesnt give an error in the main program
The point of the assignment is to create a long using linked list
class Node():
def __init__(self):
self.next = None
self.prev = None
self.data = None
def getData(self):
return self.data
class LinkedList():
def __init__(self):
self.count = 0
self.last = Node()
self.first = Node()
self.first.next = self.last
self.last.previous = self.first
def append(self, data):
self.last.data = data
self.last.next = Node()
tmp = self.last
self.last = self.last.next
self.last.previous = tmp
self.count += 1
def prepend(self, data):
self.first.data = data
self.first.previous = Node()
tmp = self.first
self.first = self.first.previous
self.first.next = tmp
self.count += 1
def front(self):
if self.count == 0: return None
return self.first.next
def back(self):
if self.count == 0: return None
return self.last.previous
def size(self):
return self.count
def __getitem__(self, node):
count = self.first
while count.data:
if count.data == node:
return count
count = count.next
return None
def __iter__(self):
count = self.first.next
while count.data:
print("here")
yield count.data
count = count.next
class BigInt:
def __init__(self, initValue = "0"):
self.data = LinkedList()
for count in initValue:
self.data.append(count)
self.Neg = False
def __repr__(self):
integer = ""
node = self.data.front()
while node.next:
integer= integer+(node.getData())
node = node.next
return "".join(integer)
def toString(self):
return self.__repr__()
def isNeg(self):
return self.Neg
def __add__(self, rhs):
node1 = self.data.back()
node2 = rhs.data.back()
if self.isNeg() and not rhs.isNeg():
return rhs - self
elif rhs.isNeg() and not self.isNeg():
return self - rhs
summation = LinkedList()
carryOne = 0
print(node1.previous.previous.getData())
while node1.previous.getData() is not None or node2.previous.getData() is not None:
tot = int(node1.getData())+int(node2.getData())+carryOne
summation.prepend((tot)%10)
carryOne = 0
if tot >= 10: carryOne = 1
node1 = node1.previous
node2 = node2.previous
ret = ""
for digit in summation:
ret = ret + digit
print(digit)
print (ret)
def __sub__():
pass
a = LinkedList()
a.prepend(4)
a.prepend(5)
a.append(23)
print (type(a.back()))
print(a.back().previous.previous.getData())
g = BigInt("2")
h = BigInt("3")
(g+h)
print (g.toString())
There's no previous member in a newly-constructed Node, only prev.
Some instances of Node will later acquire a member called previous. This is due to code like:
self.last.previous = self.first
(Thanks to #David Robinson for pointing that out.)

Categories